JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser.std; import java.io.IOException; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.deser.ContextualDeserializer; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; import com.fasterxml.jackson.databind.util.ObjectBuffer; /** * Separate implementation for serializing String arrays (instead of * using {@link ObjectArrayDeserializer}. * Used if (and only if) no custom value deserializers are used. */ @JacksonStdImpl public final class StringArrayDeserializer extends StdDeserializer<String[]> implements ContextualDeserializer { private static final long serialVersionUID = -7589512013334920693L; public final static StringArrayDeserializer instance = new StringArrayDeserializer(); /** * Value serializer to use, if not the standard one (which is inlined) */ protected JsonDeserializer<String> _elementDeserializer; public StringArrayDeserializer() { super(String[].class); _elementDeserializer = null; } @SuppressWarnings("unchecked") // [JACKSON-620] Empty String can become null... if ((jp.getCurrentToken() == JsonToken.VALUE_STRING) && ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) { String str = jp.getText(); if (str.length() == 0) { return null; } } throw ctxt.mappingException(_valueClass); } return new String[] { (jp.getCurrentToken() == JsonToken.VALUE_NULL) ? null : _parseString(jp, ctxt) }; } /** * Contextualization is needed to see whether we can "inline" deserialization * of String values, or if we have to use separate value deserializer. */ @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { JsonDeserializer<?> deser = _elementDeserializer; // #125: May have a content converter deser = findConvertingContentDeserializer(ctxt,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.File; import java.io.IOException; import java.lang.reflect.Type; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; /** * For now, File objects get serialized by just outputting * absolute (but not canonical) name as String value */ public class FileSerializer extends StdScalarSerializer<File> { public FileSerializer() { super(File.class); } @Override public void serialize(File value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeString(value.getAbsolutePath()); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("string", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { visitor.expectStringFormat(typeHint); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> { kind = Std.STD_JAVA_TYPE; } else if (rawType == Currency.class) { kind = Std.STD_CURRENCY; } else if (rawType == Pattern.class) { kind = Std.STD_PATTERN; } else if (rawType == Locale.class) { kind = Std.STD_LOCALE; } else if (rawType == Charset.class) { kind = Std.STD_CHARSET; } else if (rawType == TimeZone.class) { kind = Std.STD_TIME_ZONE; } else if (rawType == InetAddress.class) { kind = Std.STD_INET_ADDRESS; } else if (rawType == InetSocketAddress.class) { kind = Std.STD_INET_SOCKET_ADDRESS; } else { return null; } return new Std(rawType, kind); } /* /********************************************************** /* Deserializer implementations /********************************************************** */ @SuppressWarnings("unchecked") @Override public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Issue#381 if (jp.getCurrentToken() == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { jp.nextToken(); final T value = deserialize(jp, ctxt); if (jp.nextToken() != JsonToken.END_ARRAY) { throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY, "Attempted to unwrap single value array for single '" + _valueClass.getName() + "' value but there was more than a single value in the array"); } return value; } // 22-Sep-2012, tatu: For 2.1, use this new method, may force coercion: String text = jp.getValueAsString(); if (text != null) { // has String representation if (text.length() == 0 || (text = text.trim()).length() == 0) { // 04-Feb-2013, tatu: Usually should become null; but not always return _deserializeFromEmptyString(); } Exception cause = null; try { T result = _deserialize(text, ctxt

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>); if (result != null) { return result; } } catch (IllegalArgumentException iae) { cause = iae; } String msg = "not a valid textual representation"; if (cause != null) { msg += "problem: "+cause.getMessage(); } JsonMappingException e = ctxt.weirdStringException(text, _valueClass, msg); if (cause != null) { e.initCause(cause); } throw e; // nothing to do here, yet? We'll fail anyway } if (jp.getCurrentToken() == JsonToken.VALUE_EMBEDDED_OBJECT) { // Trivial cases; null to null, instance of type itself returned as is Object ob = jp.getEmbeddedObject(); if (ob == null) { return null; } if (_valueClass.isAssignableFrom(ob.getClass())) { return (T) ob; } return _deserializeEmbedded(ob, ctxt); } throw ctxt.mappingException(_valueClass); } protected abstract T _deserialize(String value, DeserializationContext ctxt) throws IOException; protected T _deserializeEmbedded(Object ob, DeserializationContext ctxt) throws IOException { // default impl: error out throw ctxt.mappingException("Don't know how to convert embedded Object of type "+ob.getClass().getName()+" into "+_valueClass.getName()); } protected T _deserializeFromEmptyString() throws IOException { return null; } /* /********************************************************** /* A general-purpose implementation /********************************************************** */ /** * "Chameleon" deserializer that works on simple types that are deserialized * from a simple String. * * @since 2.4 */ public static class Std extends FromStringDeserializer<Object> { private static final long serialVersionUID = 1; public final static int STD_FILE = 1; public final static int STD_URL = 2; public final static int STD_URI = 3; public final static int STD_CLASS = 4; public final static int STD_JAVA_TYPE = 5; public final static int STD_CURRENCY = 6; public final static int STD_PATTERN = 7; public final static int STD_LOCALE = 8; public

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> final static int STD_CHARSET = 9; public final static int STD_TIME_ZONE = 10; public final static int STD_INET_ADDRESS = 11; public final static int STD_INET_SOCKET_ADDRESS = 12; protected final int _kind; protected Std(Class<?> valueType, int kind) { super(valueType); _kind = kind; } @Override protected Object _deserialize(String value, DeserializationContext ctxt) throws IOException { switch (_kind) { case STD_FILE: return new File(value); case STD_URL: return new URL(value); case STD_URI: return URI.create(value); case STD_CLASS: try { return ctxt.findClass(value); } catch (Exception e) { throw ctxt.instantiationException(_valueClass, ClassUtil.getRootCause(e)); } case STD_JAVA_TYPE: return ctxt.getTypeFactory().constructFromCanonical(value); case STD_CURRENCY: // will throw IAE if unknown: return Currency.getInstance(value); case STD_PATTERN: // will throw IAE (or its subclass) if malformed return Pattern.compile(value); case STD_LOCALE: { int ix = value.indexOf('_'); if (ix < 0) { // single argument return new Locale(value); } String first = value.substring(0, ix); value = value.substring(ix+1); ix = value.indexOf('_'); if (ix < 0) { // two pieces return new Locale(first, value); } String second = value.substring(0, ix); return new Locale(first, second, value.substring(ix+1)); } case STD_CHARSET: return Charset.forName(value); case STD_TIME_ZONE: return TimeZone.getTimeZone(value); case STD_INET_ADDRESS: return InetAddress.getByName(value); case STD_INET_SOCKET_ADDRESS: if (value.startsWith("[")) { // bracketed IPv6 (with port number) int i = value.lastIndexOf(']'); if (i == -1) { throw new InvalidFormatException("Bracketed

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.exc; import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonMappingException; /** * Specialized sub-class of {@link JsonMappingException} * that is used when the underlying problem appears to be that * of bad formatting of a value to deserialize. * * @since 2.1 */ public class InvalidFormatException extends JsonMappingException { private static final long serialVersionUID = 1L; // silly Eclipse, warnings /** * Underlying value that could not be deserialized into * target type, if available. */ protected final Object _value; /** * Intended target type (type-erased class) that value could not * be deserialized into, if known. */ protected final Class<?> _targetType; /* /********************************************************** /* Life-cycle /********************************************************** */ public InvalidFormatException(String msg, Object value, Class<?> targetType) { super(msg); _value = value; _targetType = targetType; } public InvalidFormatException(String msg, JsonLocation loc, Object value, Class<?> targetType) { super(msg, loc); _value = value; _targetType = targetType; } public static InvalidFormatException from(JsonParser jp, String msg, Object value, Class<?> targetType) { return new InvalidFormatException(msg, jp.getTokenLocation(), value, targetType); } /* /********************************************************** /* Additional accessors /********************************************************** */ /** * Accessor for checking source value (String, Number usually) that could not * be deserialized into target type ({@link #getTargetType}). * Note that value may not be available, depending on who throws the exception * and when. */ public Object getValue() { return _value; } /** * Accessor for checking target type of value ({@link #getValue} that failed * to deserialize. * Note that type may not be available, depending on who throws the exception * and when. */ public Class<?> getTargetType() { return _targetType; } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>; _delegateDeserializer = (JsonDeserializer<Object>) delegateDeserializer; } /** * Method used for creating resolved contextual instances. Must be * overridden when sub-classing. */ protected StdDelegatingDeserializer<T> withDelegate(Converter<Object,T> converter, JavaType delegateType, JsonDeserializer<?> delegateDeserializer) { if (getClass() != StdDelegatingDeserializer.class) { throw new IllegalStateException("Sub-class "+getClass().getName()+" must override 'withDelegate'"); } return new StdDelegatingDeserializer<T>(converter, delegateType, delegateDeserializer); } /* /********************************************************** /* Contextualization /********************************************************** */ @Override public void resolve(DeserializationContext ctxt) throws JsonMappingException { if (_delegateDeserializer != null && _delegateDeserializer instanceof ResolvableDeserializer) { ((ResolvableDeserializer) _delegateDeserializer).resolve(ctxt); } } @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { // First: if already got serializer to delegate to, contextualize it: if (_delegateDeserializer != null) { JsonDeserializer<?> deser = ctxt.handleSecondaryContextualization(_delegateDeserializer, property); if (deser != _delegateDeserializer) { return withDelegate(_converter, _delegateType, deser); } return this; } // Otherwise: figure out what is the fully generic delegate type, then find deserializer JavaType delegateType = _converter.getInputType(ctxt.getTypeFactory()); return withDelegate(_converter, delegateType, ctxt.findContextualValueDeserializer(delegateType, property)); } /* /********************************************************** /* Accessors /********************************************************** */ @Override public JsonDeserializer<?> getDelegatee() { return _delegateDeserializer; } @Override public Class<?> handledType() { return _delegateDeserializer.handledType(); } /* /********************************************************** /* Serialization /********************************************************** */ @Override public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { Object delegateValue = _delegateDeserializer.deserialize(jp, ctxt); if (delegateValue == null) { return null; } return convertValue(delegateValue); } @Override

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> Enum<?> result = _resolver.getEnum(ix); if (result != null) { return result; } } catch (NumberFormatException e) { // fine, ignore, was not an integer } } } if (!ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) { throw ctxt.weirdStringException(name, _resolver.getEnumClass(), "value not one of declared Enum instance names: "+_resolver.getEnums()); } return null; } private final Enum<?> _deserializeOther(JsonParser jp, DeserializationContext ctxt) throws IOException { JsonToken curr = jp.getCurrentToken(); // Issue#381 if (curr == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { jp.nextToken(); final Enum<?> parsed = deserialize(jp, ctxt); curr = jp.nextToken(); if (curr != JsonToken.END_ARRAY) { throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY, "Attempted to unwrap single value array for single '" + _resolver.getEnumClass().getName() + "' value but there was more than a single value in the array"); } return parsed; } throw ctxt.mappingException(_resolver.getEnumClass()); } /* /********************************************************** /* Additional helper classes /********************************************************** */ /** * Deserializer that uses a single-String static factory method * for locating Enum values by String id. */ protected static class FactoryBasedDeserializer extends StdScalarDeserializer<Object> { private static final long serialVersionUID = -7775129435872564122L; protected final Class<?> _enumClass; // Marker type; null if String expected; otherwise numeric wrapper protected final Class<?> _inputType; protected final Method _factory; public FactoryBasedDeserializer(Class<?> cls, AnnotatedMethod f, Class<?> inputType) { super(Enum.class); _enumClass = cls; _factory = f.getAnnotated(); _inputType = inputType; } @Override public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, Json

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>ProcessingException { // couple of accepted types... Object value; if (_inputType == null) { value = jp.getText(); } else if (_inputType == Integer.class) { value = Integer.valueOf(jp.getValueAsInt()); } else if (_inputType == Long.class) { value = Long.valueOf(jp.getValueAsLong()); } else { throw ctxt.mappingException(_enumClass); } try { return _factory.invoke(_enumClass, value); } catch (Exception e) { Throwable t = ClassUtil.getRootCause(e); if (t instanceof IOException) { throw (IOException) t; } throw ctxt.instantiationException(_enumClass, t); } } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.exc; import java.util.Collection; import java.util.Collections; import java.util.Iterator; import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.databind.JsonMappingException; /** * Base class for {@link JsonMappingException}s that are specifically related * to problems related to binding an individual property. * * @since 2.3 */ @SuppressWarnings("serial") public abstract class PropertyBindingException extends JsonMappingException { /** * Class that does not contain mapping for the unrecognized property. */ protected final Class<?> _referringClass; /** *<p> * Note: redundant information since it is also included in the * reference path. */ protected final String _propertyName; /** * Set of ids of properties that are known for the type, if this * can be statically determined. */ protected final Collection<Object> _propertyIds; /** * Lazily constructed description of known properties, used for * constructing actual message if and as needed. */ protected transient String _propertiesAsString; protected PropertyBindingException(String msg, JsonLocation loc, Class<?> referringClass, String propName, Collection<Object> propertyIds) { super(msg, loc); _referringClass = referringClass; _propertyName = propName; _propertyIds = propertyIds; } /* /********************************************************** /* Overrides /********************************************************** */ private final static int MAX_DESC_LENGTH = 200; @Override public String getMessageSuffix() { String suffix = _propertiesAsString; if (suffix == null && _propertyIds != null) { StringBuilder sb = new StringBuilder(100); int len = _propertyIds.size(); if (len == 1) { sb.append(" (one known property: \""); sb.append(String.valueOf(_propertyIds.iterator().next())); sb.append('"'); } else { sb.append(" (").append(len).append(" known properties: "); Iterator<Object> it = _propertyIds.iterator(); while (it.hasNext()) { sb.append('"'); sb.append(String.valueOf

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> MyTokenizer tokens) { try { return ClassUtil.findClass(className); } catch (Exception e) { if (e instanceof RuntimeException) { throw (RuntimeException) e; } throw _problem(tokens, "Can not locate class '"+className+"', problem: "+e.getMessage()); } } protected IllegalArgumentException _problem(MyTokenizer tokens, String msg) { return new IllegalArgumentException("Failed to parse type '"+tokens.getAllInput() +"' (remaining: '"+tokens.getRemainingInput()+"'): "+msg); } final static class MyTokenizer extends StringTokenizer { protected final String _input; protected int _index; protected String _pushbackToken; public MyTokenizer(String str) { super(str, "<,>", true); _input = str; } @Override public boolean hasMoreTokens() { return (_pushbackToken != null) || super.hasMoreTokens(); } @Override public String nextToken() { String token; if (_pushbackToken != null) { token = _pushbackToken; _pushbackToken = null; } else { token = super.nextToken(); } _index += token.length(); return token; } public void pushBack(String token) { _pushbackToken = token; _index -= token.length(); } public String getAllInput() { return _input; } public String getUsedInput() { return _input.substring(0, _index); } public String getRemainingInput() { return _input.substring(_index); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>AsIndex; } /** * Factory method used by {@link com.fasterxml.jackson.databind.ser.BasicSerializerFactory} * for constructing serializer instance of Enum types. * * @since 2.1 */ public static EnumSerializer construct(Class<Enum<?>> enumClass, SerializationConfig config, BeanDescription beanDesc, JsonFormat.Value format) { // [JACKSON-212]: If toString() is to be used instead, leave EnumValues null EnumValues v = EnumValues.construct(config, enumClass); Boolean serializeAsIndex = _isShapeWrittenUsingIndex(enumClass, format, true); return new EnumSerializer(v, serializeAsIndex); } /** * To support some level of per-property configuration, we will need * to make things contextual. We are limited to "textual vs index" * choice here, however. */ @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { if (property != null) { JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat((Annotated) property.getMember()); if (format != null) { Boolean serializeAsIndex = _isShapeWrittenUsingIndex(property.getType().getRawClass(), format, false); if (serializeAsIndex != _serializeAsIndex) { return new EnumSerializer(_values, serializeAsIndex); } } } return this; } /* /********************************************************** /* Extended API for Jackson databind core /********************************************************** */ public EnumValues getEnumValues() { return _values; } /* /********************************************************** /* Actual serialization /********************************************************** */ @Override public final void serialize(Enum<?> en, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { // [JACKSON-684]: serialize as index? if (_serializeAsIndex(provider)) { jgen.writeNumber(en.ordinal()); return; } jgen.writeString(_values.serializedValueFor(en)); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { // [JACKSON-684]: serialize as index? if (_serializeAsIndex(provider))

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> { return createSchemaNode("integer", true); } ObjectNode objectNode = createSchemaNode("string", true); if (typeHint != null) { JavaType type = provider.constructType(typeHint); if (type.isEnumType()) { ArrayNode enumNode = objectNode.putArray("enum"); for (SerializableString value : _values.values()) { enumNode.add(value.getValue()); } } } return objectNode; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { // [JACKSON-684]: serialize as index? if (visitor.getProvider().isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX)) { JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint); if (v2 != null) { // typically serialized as a small number (byte or int) v2.numberType(JsonParser.NumberType.INT); } } else { JsonStringFormatVisitor stringVisitor = visitor.expectStringFormat(typeHint); if (typeHint != null && stringVisitor != null) { if (typeHint.isEnumType()) { Set<String> enums = new LinkedHashSet<String>(); for (SerializableString value : _values.values()) { enums.add(value.getValue()); } stringVisitor.enumTypes(enums); } } } } /* /********************************************************** /* Helper methods /********************************************************** */ protected final boolean _serializeAsIndex(SerializerProvider provider) { if (_serializeAsIndex != null) { return _serializeAsIndex.booleanValue(); } return provider.isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX); } /** * Helper method called to check whether */ protected static Boolean _isShapeWrittenUsingIndex(Class<?> enumClass, JsonFormat.Value format, boolean fromClass) { JsonFormat.Shape shape = (format == null) ? null : format.getShape(); if (shape == null) { return null; } if (shape == Shape.ANY || shape == Shape.SCALAR) { // i

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { // Hmmh. What should it be? Ideally should probably indicate BIG_DECIMAL // to ensure no information is lost? But probably won't work that well... JsonNumberFormatVisitor v2 = visitor.expectNumberFormat(typeHint); if (v2 != null) { v2.numberType(JsonParser.NumberType.BIG_DECIMAL); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.exc; import java.util.*; import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonMappingException; /** * Specialized {@link JsonMappingException} sub-class specifically used * to indicate problems due to encountering a JSON property that could * not be mapped to an Object property (via getter, constructor argument * or field). */ public class UnrecognizedPropertyException extends PropertyBindingException { private static final long serialVersionUID = 1L; public UnrecognizedPropertyException(String msg, JsonLocation loc, Class<?> referringClass, String propName, Collection<Object> propertyIds) { super(msg, loc, referringClass, propName, propertyIds); } /** * Factory method used for constructing instances of this exception type. * * @param jp Underlying parser used for reading input being used for data-binding * @param fromObjectOrClass Reference to either instance of problematic type ( * if available), or if not, type itself * @param propertyName Name of unrecognized property * @param propertyIds (optional, null if not available) Set of properties that * type would recognize, if completely known: null if set can not be determined. */ public static UnrecognizedPropertyException from(JsonParser jp, Object fromObjectOrClass, String propertyName, Collection<Object> propertyIds) { if (fromObjectOrClass == null) { throw new IllegalArgumentException(); } Class<?> ref; if (fromObjectOrClass instanceof Class<?>) { ref = (Class<?>) fromObjectOrClass; } else { ref = fromObjectOrClass.getClass(); } String msg = "Unrecognized field \""+propertyName+"\" (class "+ref.getName()+"), not marked as ignorable"; UnrecognizedPropertyException e = new UnrecognizedPropertyException(msg, jp.getCurrentLocation(), ref, propertyName, propertyIds); // but let's also ensure path includes this last (missing) segment e.prependPath(fromObjectOrClass, propertyName); return e; } /** * @deprecated Since 2.3, use {@link #getPropertyName} instead. */ @Deprecated

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> = roid.referringProperties(); iterator.hasNext();) { Referring referring = iterator.next(); exception.addUnresolvedId(roid.getKey().key, referring.getBeanType(), referring.getLocation()); } } } if (exception != null) { throw exception; } } /* /********************************************************** /* Abstract methods impls, other factory methods /********************************************************** */ @SuppressWarnings("unchecked") @Override public JsonDeserializer<Object> deserializerInstance(Annotated ann, Object deserDef) throws JsonMappingException { if (deserDef == null) { return null; } JsonDeserializer<?> deser; if (deserDef instanceof JsonDeserializer) { deser = (JsonDeserializer<?>) deserDef; } else { /* Alas, there's no way to force return type of "either class * X or Y" -- need to throw an exception after the fact */ if (!(deserDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned deserializer definition of type "+deserDef.getClass().getName()+"; expected type JsonDeserializer or Class<JsonDeserializer> instead"); } Class<?> deserClass = (Class<?>)deserDef; // there are some known "no class" markers to consider too: if (deserClass == JsonDeserializer.None.class || ClassUtil.isBogusClass(deserClass)) { return null; } if (!JsonDeserializer.class.isAssignableFrom(deserClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class "+deserClass.getName()+"; expected Class<JsonDeserializer>"); } HandlerInstantiator hi = _config.getHandlerInstantiator(); deser = (hi == null) ? null : hi.deserializerInstance(_config, ann, deserClass); if (deser == null) { deser = (JsonDeserializer<?>) ClassUtil.createInstance(deserClass, _config.canOverrideAccessModifiers()); } } // First: need to resolve if (deser instanceof ResolvableDeserializer) { ((ResolvableDeserializer) deser).resolve(this); } return (JsonDeserializer<Object>) deser; } @Override public final KeyDeserializer keyDeserializerInstance(Annotated ann, Object deserDef) throws JsonMappingException {

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>(): first argument not of type String or Object, but "+type.getName()); } } return _anySetterMethod; } @Override public Map<Object, AnnotatedMember> findInjectables() { return _injectables; } @Override public List<AnnotatedConstructor> getConstructors() { return _classInfo.getConstructors(); } @Override public Object instantiateBean(boolean fixAccess) { AnnotatedConstructor ac = _classInfo.getDefaultConstructor(); if (ac == null) { return null; } if (fixAccess) { ac.fixAccess(); } try { return ac.getAnnotated().newInstance(); } catch (Exception e) { Throwable t = e; while (t.getCause() != null) { t = t.getCause(); } if (t instanceof Error) throw (Error) t; if (t instanceof RuntimeException) throw (RuntimeException) t; throw new IllegalArgumentException("Failed to instantiate bean of type "+_classInfo.getAnnotated().getName()+": ("+t.getClass().getName()+") "+t.getMessage(), t); } } /* /********************************************************** /* Simple accessors, extended /********************************************************** */ @Override public AnnotatedMethod findMethod(String name, Class<?>[] paramTypes) { return _classInfo.findMethod(name, paramTypes); } /* /********************************************************** /* General per-class annotation introspection /********************************************************** */ @Override public JsonFormat.Value findExpectedFormat(JsonFormat.Value defValue) { if (_annotationIntrospector != null) { JsonFormat.Value v = _annotationIntrospector.findFormat(_classInfo); if (v != null) { return v; } } return defValue; } /* /********************************************************** /* Introspection for serialization /********************************************************** */ @Override public Converter<Object,Object> findSerializationConverter() { if (_annotationIntrospector == null) { return null; } return _createConverter(_annotationIntrospector.findSerializationConverter(_classInfo)); } /** * Method for determining whether null properties should be written * out for a Bean of introspected type. This is based on global

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Deprecated // since 2.3 -- use 'withSimpleName' instead if need be public SettableBeanProperty withName(String simpleName) { return withName(new PropertyName(simpleName)); } public void setManagedReferenceName(String n) { _managedReferenceName = n; } public void setObjectIdInfo(ObjectIdInfo objectIdInfo) { _objectIdInfo = objectIdInfo; } public void setViews(Class<?>[] views) { if (views == null) { _viewMatcher = null; } else { _viewMatcher = ViewMatcher.construct(views); } } /** * Method used to assign index for property. */ public void assignIndex(int index) { if (_propertyIndex != -1) { throw new IllegalStateException("Property '"+getName()+"' already had index ("+_propertyIndex+"), trying to assign "+index); } _propertyIndex = index; } /* /********************************************************** /* BeanProperty impl /********************************************************** */ @Override public final String getName() { return _propName.getSimpleName(); } @Override public PropertyName getFullName() { return _propName; } @Override public boolean isRequired() { return _metadata.isRequired(); } @Override public PropertyMetadata getMetadata() { return _metadata; } @Override public JavaType getType() { return _type; } @Override public PropertyName getWrapperName() { return _wrapperName; } @Override public abstract <A extends Annotation> A getAnnotation(Class<A> acls); @Override public abstract AnnotatedMember getMember(); @Override public <A extends Annotation> A getContextAnnotation(Class<A> acls) { return _contextAnnotations.get(acls); } @Override public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor) throws JsonMappingException { if (isRequired()) { objectVisitor.property(this); } else { objectVisitor.optionalProperty(this); } } /* /********************************************************** /* Accessors /********************************************************** */ protected final Class<?> getDeclaringClass() { return getMember().getDeclaringClass(); } public String getManagedReferenceName() { return _

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>AsIOE(Exception e, Object value) throws IOException { if (e instanceof IllegalArgumentException) { String actType = (value == null) ? "[NULL]" : value.getClass().getName(); StringBuilder msg = new StringBuilder("Problem deserializing property '").append(getName()); msg.append("' (expected type: ").append(getType()); msg.append("; actual type: ").append(actType).append(")"); String origMsg = e.getMessage(); if (origMsg != null) { msg.append(", problem: ").append(origMsg); } else { msg.append(" (no error message provided)"); } throw new JsonMappingException(msg.toString(), null, e); } _throwAsIOE(e); } protected IOException _throwAsIOE(Exception e) throws IOException { if (e instanceof IOException) { throw (IOException) e; } if (e instanceof RuntimeException) { throw (RuntimeException) e; } // let's wrap the innermost problem Throwable th = e; while (th.getCause() != null) { th = th.getCause(); } throw new JsonMappingException(th.getMessage(), null, th); } @Override public String toString() { return "[property '"+getName()+"']"; } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Type, keyDeserializer, valueDeserializer, _valueTypeDeserializer); } /** * Method called to finalize setup of this deserializer, * when it is known for which property deserializer is needed for. */ @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { // note: instead of finding key deserializer, with enums we actually // work with regular deserializers (less code duplication; but not // quite as clean as it ought to be) JsonDeserializer<?> kd = _keyDeserializer; if (kd == null) { kd = ctxt.findContextualValueDeserializer(_mapType.getKeyType(), property); } JsonDeserializer<?> vd = _valueDeserializer; if (vd == null) { vd = ctxt.findContextualValueDeserializer(_mapType.getContentType(), property); } else { // if directly assigned, probably not yet contextual, so: vd = ctxt.handleSecondaryContextualization(vd, property); } TypeDeserializer vtd = _valueTypeDeserializer; if (vtd != null) { vtd = vtd.forProperty(property); } return withResolved(kd, vd, vtd); } /** * Because of costs associated with constructing Enum resolvers, * let's cache instances by default. */ @Override public boolean isCachable() { return true; } /* /********************************************************** /* Actual deserialization /********************************************************** */ @Override public EnumMap<?,?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // Ok: must point to START_OBJECT if (jp.getCurrentToken() != JsonToken.START_OBJECT) { throw ctxt.mappingException(EnumMap.class); } EnumMap result = constructMap(); final JsonDeserializer<Object> valueDes = _valueDeserializer; final TypeDeserializer typeDeser = _valueTypeDeserializer; while ((jp.nextToken()) != JsonToken.END_OBJECT) { Enum<?> key = _keyDeserializer.deserialize(jp, ctxt); if (key == null) { if (!ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) { String value = null; try { // bit ugly, but will

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> have to do; works with usual scalars if (jp.hasCurrentToken()) { value = jp.getText(); } } catch (Exception e) { } throw ctxt.weirdStringException(value, _enumClass, "value not one of declared Enum instance names"); } /* 24-Mar-2012, tatu: Null won't work as a key anyway, so let's * just skip the entry then. But we must skip the value then. */ jp.nextToken(); jp.skipChildren(); continue; } // And then the value... JsonToken t = jp.nextToken(); /* note: MUST check for nulls separately: deserializers will * not handle them (and maybe fail or return bogus data) */ Object value; if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(); } else if (typeDeser == null) { value = valueDes.deserialize(jp, ctxt); } else { value = valueDes.deserializeWithType(jp, ctxt, typeDeser); } result.put(key, value); } return result; } @Override public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException, JsonProcessingException { // In future could check current token... for now this should be enough: return typeDeserializer.deserializeTypedFromObject(jp, ctxt); } private EnumMap<?,?> constructMap() { return new EnumMap(_enumClass); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser.std; import java.io.IOException; import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.ContextualDeserializer; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; public class AtomicReferenceDeserializer extends StdDeserializer<AtomicReference<?>> implements ContextualDeserializer { private static final long serialVersionUID = 1L; /** * Type of value that we reference */ protected final JavaType _referencedType; protected final TypeDeserializer _valueTypeDeserializer; protected final JsonDeserializer<?> _valueDeserializer; /** * @param referencedType Parameterization of this reference */ public AtomicReferenceDeserializer(JavaType referencedType) { this(referencedType, null, null); } public AtomicReferenceDeserializer(JavaType referencedType, TypeDeserializer typeDeser, JsonDeserializer<?> deser) { super(AtomicReference.class); _referencedType = referencedType; _valueDeserializer = deser; _valueTypeDeserializer = typeDeser; } public AtomicReferenceDeserializer withResolved(TypeDeserializer typeDeser, JsonDeserializer<?> valueDeser) { return new AtomicReferenceDeserializer(_referencedType, typeDeser, valueDeser); } // Added in 2.3 @Override public AtomicReference<?> getNullValue() { return new AtomicReference<Object>(); } @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { JsonDeserializer<?> deser = _valueDeserializer; TypeDeserializer typeDeser = _valueTypeDeserializer; if (deser == null) { deser = ctxt.findContextualValueDeserializer(_referencedType, property); } if (typeDeser != null) { typeDeser = typeDeser.forProperty(property); } if (deser == _valueDeserializer && typeDeser == _valueTypeDeserializer) { return this; } return withResolved(typeDeser, deser); } @Override public AtomicReference<?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { /* 06-Nov-2013, tatu: Looks like the

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> canBeABeanType(Class<?> type) { // First: language constructs that ain't beans: if (type.isAnnotation()) { return "annotation"; } if (type.isArray()) { return "array"; } if (type.isEnum()) { return "enum"; } if (type.isPrimitive()) { return "primitive"; } // Anything else? Seems valid, then return null; } public static String isLocalType(Class<?> type, boolean allowNonStatic) { /* As per [JACKSON-187], GAE seems to throw SecurityExceptions * here and there... and GAE itself has a bug, too * (see []). Bah. So we need to catch some wayward exceptions on GAE */ try { // one more: method locals, anonymous, are not good: if (type.getEnclosingMethod() != null) { return "local/anonymous"; } /* But how about non-static inner classes? Can't construct * easily (theoretically, we could try to check if parent * happens to be enclosing... but that gets convoluted) */ if (!allowNonStatic) { if (type.getEnclosingClass() != null) { if (!Modifier.isStatic(type.getModifiers())) { return "non-static member class"; } } } } catch (SecurityException e) { } catch (NullPointerException e) { } return null; } /** * Method for finding enclosing class for non-static inner classes */ public static Class<?> getOuterClass(Class<?> type) { // as above, GAE has some issues... try { // one more: method locals, anonymous, are not good: if (type.getEnclosingMethod() != null) { return null; } if (!Modifier.isStatic(type.getModifiers())) { return type.getEnclosingClass(); } } catch (SecurityException e) { } catch (NullPointerException e) { } return null; } /** * Helper method used to weed out dynamic Proxy types; types that do * not expose concrete method API that we could use to figure out * automatic Bean (

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> if ("int".equals(className)) return Integer.TYPE; if ("long".equals(className)) return Long.TYPE; if ("float".equals(className)) return Float.TYPE; if ("double".equals(className)) return Double.TYPE; if ("boolean".equals(className)) return Boolean.TYPE; if ("byte".equals(className)) return Byte.TYPE; if ("char".equals(className)) return Character.TYPE; if ("short".equals(className)) return Short.TYPE; if ("void".equals(className)) return Void.TYPE; } // Two-phase lookup: first using context ClassLoader; then default Throwable prob = null; ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (loader != null) { try { return Class.forName(className, true, loader); } catch (Exception e) { prob = getRootCause(e); } } try { return Class.forName(className); } catch (Exception e) { if (prob == null) { prob = getRootCause(e); } } if (prob instanceof RuntimeException) { throw (RuntimeException) prob; } throw new ClassNotFoundException(prob.getMessage(), prob); } /* /********************************************************** /* Method type detection methods /********************************************************** */ public static boolean hasGetterSignature(Method m) { // First: static methods can't be getters if (Modifier.isStatic(m.getModifiers())) { return false; } // Must take no args Class<?>[] pts = m.getParameterTypes(); if (pts != null && pts.length != 0) { return false; } // Can't be a void method if (Void.TYPE == m.getReturnType()) { return false; } // Otherwise looks ok: return true; } /* /********************************************************** /* Exception handling /********************************************************** */ /** * Method that can be used to find the "root cause", innermost * of chained (wrapped) exceptions. */ public static Throwable getRootCause(Throwable t) { while (t.getCause() != null) { t = t.getCause(); } return t; } /** * Method that will unwrap root causes of given

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> Throwable, and throw * the innermost {@link Exception} or {@link Error} as is. * This is useful in cases where mandatory wrapping is added, which * is often done by Reflection API. */ public static void throwRootCause(Throwable t) throws Exception { t = getRootCause(t); if (t instanceof Exception) { throw (Exception) t; } throw (Error) t; } /** * Method that will wrap 't' as an {@link IllegalArgumentException} if it * is a checked exception; otherwise (runtime exception or error) throw as is */ public static void throwAsIAE(Throwable t) { throwAsIAE(t, t.getMessage()); } /** * Method that will wrap 't' as an {@link IllegalArgumentException} (and with * specified message) if it * is a checked exception; otherwise (runtime exception or error) throw as is */ public static void throwAsIAE(Throwable t, String msg) { if (t instanceof RuntimeException) { throw (RuntimeException) t; } if (t instanceof Error) { throw (Error) t; } throw new IllegalArgumentException(msg, t); } /** * Method that will locate the innermost exception for given Throwable; * and then wrap it as an {@link IllegalArgumentException} if it * is a checked exception; otherwise (runtime exception or error) throw as is */ public static void unwrapAndThrowAsIAE(Throwable t) { throwAsIAE(getRootCause(t)); } /** * Method that will locate the innermost exception for given Throwable; * and then wrap it as an {@link IllegalArgumentException} if it * is a checked exception; otherwise (runtime exception or error) throw as is */ public static void unwrapAndThrowAsIAE(Throwable t, String msg) { throwAsIAE(getRootCause(t), msg); } /* /********************************************************** /* Instantiation /********************************************************** */ /** * Method that can be called to try to create an instantiate of * specified type. Instantiation is done using default no-argument * constructor. * * @param canFixAccess Whether it is possible to try to change access * rights of the default constructor (in

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> case it is not publicly * accessible) or not. * * @throws IllegalArgumentException If instantiation fails for any reason; * except for cases where constructor throws an unchecked exception * (which will be passed as is) */ public static <T> T createInstance(Class<T> cls, boolean canFixAccess) throws IllegalArgumentException { Constructor<T> ctor = findConstructor(cls, canFixAccess); if (ctor == null) { throw new IllegalArgumentException("Class "+cls.getName()+" has no default (no arg) constructor"); } try { return ctor.newInstance(); } catch (Exception e) { ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+cls.getName()+", problem: "+e.getMessage()); return null; } } public static <T> Constructor<T> findConstructor(Class<T> cls, boolean canFixAccess) throws IllegalArgumentException { try { Constructor<T> ctor = cls.getDeclaredConstructor(); if (canFixAccess) { checkAndFixAccess(ctor); } else { // Has to be public... if (!Modifier.isPublic(ctor.getModifiers())) { throw new IllegalArgumentException("Default constructor for "+cls.getName()+" is not accessible (non-public?): not allowed to try modify access via Reflection: can not instantiate type"); } } return ctor; } catch (NoSuchMethodException e) { ; } catch (Exception e) { ClassUtil.unwrapAndThrowAsIAE(e, "Failed to find default constructor of class "+cls.getName()+", problem: "+e.getMessage()); } return null; } /* /********************************************************** /* Primitive type support /********************************************************** */ /** * Helper method used to get default value for wrappers used for primitive types * (0 for Integer etc) */ public static Object defaultValue(Class<?> cls) { if (cls == Integer.TYPE) { return Integer.valueOf(0); } if (cls == Long.TYPE) { return Long.valueOf(0L); } if (cls == Boolean.TYPE) { return Boolean.FALSE; } if (cls == Double.TYPE) { return Double.valueOf(0.0); } if

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> /* JDK uses following fields to store information about actual Enumeration * type for EnumSets, EnumMaps... */ enumSetTypeField = locateField(EnumSet.class, "elementType", Class.class); enumMapTypeField = locateField(EnumMap.class, "elementType", Class.class); } @SuppressWarnings("unchecked") public Class<? extends Enum<?>> enumTypeFor(EnumSet<?> set) { if (enumSetTypeField != null) { return (Class<? extends Enum<?>>) get(set, enumSetTypeField); } throw new IllegalStateException("Can not figure out type for EnumSet (odd JDK platform?)"); } @SuppressWarnings("unchecked") public Class<? extends Enum<?>> enumTypeFor(EnumMap<?,?> set) { if (enumMapTypeField != null) { return (Class<? extends Enum<?>>) get(set, enumMapTypeField); } throw new IllegalStateException("Can not figure out type for EnumMap (odd JDK platform?)"); } private Object get(Object bean, Field field) { try { return field.get(bean); } catch (Exception e) { throw new IllegalArgumentException(e); } } private static Field locateField(Class<?> fromClass, String expectedName, Class<?> type) { Field found = null; // First: let's see if we can find exact match: Field[] fields = fromClass.getDeclaredFields(); for (Field f : fields) { if (expectedName.equals(f.getName()) && f.getType() == type) { found = f; break; } } // And if not, if there is just one field with the type, that field if (found == null) { for (Field f : fields) { if (f.getType() == type) { // If more than one, can't choose if (found != null) return null; found = f; } } } if (found != null) { // it's non-public, need to force accessible try {

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> instead. */ @Deprecated public JsonFactory getJsonFactory() { return _generatorFactory; } /** * @since 2.2 */ public JsonFactory getFactory() { return _generatorFactory; } public TypeFactory getTypeFactory() { return _config.getTypeFactory(); } /** * Diagnostics method that can be called to check whether this writer * has pre-fetched serializer to use: pre-fetching improves performance * when writer instances are reused as it avoids a per-call serializer * lookup. * * @since 2.2 */ public boolean hasPrefetchedSerializer() { return _rootSerializer != null; } /** * @since 2.3 */ public ContextAttributes getAttributes() { return _config.getAttributes(); } /* /********************************************************** /* Serialization methods; ones from ObjectCodec first /********************************************************** */ /** * Method that can be used to serialize any Java value as * JSON output, using provided {@link JsonGenerator}. */ public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException { // 10-Aug-2012, tatu: As per [Issue#12], may need to force PrettyPrinter settings, so: _configureJsonGenerator(jgen); if (_config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _writeCloseableValue(jgen, value, _config); } else { if (_rootType == null) { _serializerProvider(_config).serializeValue(jgen, value); } else { _serializerProvider(_config).serializeValue(jgen, value, _rootType, _rootSerializer); } if (_config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } } } /* /********************************************************** /* Serialization methods, others /********************************************************** */ /** * Method that can be used to serialize any Java value as * JSON output, written to File provided. */ public void writeValue(File resultFile, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_generatorFactory

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>.createGenerator(resultFile, JsonEncoding.UTF8), value); } /** * Method that can be used to serialize any Java value as * JSON output, using output stream provided (using encoding * {@link JsonEncoding#UTF8}). *<p> * Note: method does not close the underlying stream explicitly * here; however, {@link JsonFactory} this mapper uses may choose * to close the stream depending on its settings (by default, * it will try to close it when {@link JsonGenerator} we construct * is closed). */ public void writeValue(OutputStream out, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_generatorFactory.createGenerator(out, JsonEncoding.UTF8), value); } /** * Method that can be used to serialize any Java value as * JSON output, using Writer provided. *<p> * Note: method does not close the underlying stream explicitly * here; however, {@link JsonFactory} this mapper uses may choose * to close the stream depending on its settings (by default, * it will try to close it when {@link JsonGenerator} we construct * is closed). */ public void writeValue(Writer w, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_generatorFactory.createGenerator(w), value); } /** * Method that can be used to serialize any Java value as * a String. Functionally equivalent to calling * {@link #writeValue(Writer,Object)} with {@link java.io.StringWriter} * and constructing String, but more efficient. *<p> * Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it. */ @SuppressWarnings("resource") public String writeValueAsString(Object value) throws JsonProcessingException { // alas, we have to pull the recycler directly here... SegmentedStringWriter sw = new SegmentedStringWriter(_generatorFactory._getBufferRecycler()); try { _configAndWriteValue(_generatorFactory.createGenerator(sw), value); } catch (JsonProcessingException e) { // to support [JACKSON-758] throw e; } catch (IOException e

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>) { // shouldn't really happen, but is declared as possibility so: throw JsonMappingException.fromUnexpectedIOE(e); } return sw.getAndClear(); } /** * Method that can be used to serialize any Java value as * a byte array. Functionally equivalent to calling * {@link #writeValue(Writer,Object)} with {@link java.io.ByteArrayOutputStream} * and getting bytes, but more efficient. * Encoding used will be UTF-8. *<p> * Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it. */ @SuppressWarnings("resource") public byte[] writeValueAsBytes(Object value) throws JsonProcessingException { ByteArrayBuilder bb = new ByteArrayBuilder(_generatorFactory._getBufferRecycler()); try { _configAndWriteValue(_generatorFactory.createGenerator(bb, JsonEncoding.UTF8), value); } catch (JsonProcessingException e) { // to support [JACKSON-758] throw e; } catch (IOException e) { // shouldn't really happen, but is declared as possibility so: throw JsonMappingException.fromUnexpectedIOE(e); } byte[] result = bb.toByteArray(); bb.release(); return result; } /* /********************************************************** /* Other public methods /********************************************************** */ /** * Method for visiting type hierarchy for given type, using specified visitor. * Visitation uses <code>Serializer</code> hierarchy and related properties *<p> * This method can be used for things like * generating <a href="http://json-schema.org/">Json Schema</a> * instance for specified type. * * @param type Type to generate schema for (possibly with generic signature) * * @since 2.2 */ public void acceptJsonFormatVisitor(JavaType type, JsonFormatVisitorWrapper visitor) throws JsonMappingException { if (type == null) { throw new IllegalArgumentException("type must be provided"); } _serializerProvider(_config).acceptJsonFormatVisitor(type, visitor); } public boolean canSerialize(Class<?> type) { return _serializerProvider(_config).hasSerializerFor(type, null); } /** * Method

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> jgen.disable(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT); try { jgen.close(); } catch (IOException ioe) { } } } } /** * Helper method used when value to serialize is {@link Closeable} and its <code>close()</code> * method is to be called right after serialization has been called */ private final void _writeCloseable(JsonGenerator jgen, Object value, SerializationConfig cfg) throws IOException, JsonGenerationException, JsonMappingException { Closeable toClose = (Closeable) value; try { if (_rootType == null) { _serializerProvider(cfg).serializeValue(jgen, value); } else { _serializerProvider(cfg).serializeValue(jgen, value, _rootType, _rootSerializer); } JsonGenerator tmpJgen = jgen; jgen = null; tmpJgen.close(); Closeable tmpToClose = toClose; toClose = null; tmpToClose.close(); } finally { /* Need to close both generator and value, as long as they haven't yet * been closed */ if (jgen != null) { /* 04-Mar-2014, tatu: But! Let's try to prevent auto-closing of * structures, which typically causes more damage. */ jgen.disable(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT); try { jgen.close(); } catch (IOException ioe) { } } if (toClose != null) { try { toClose.close(); } catch (IOException ioe) { } } } } /** * Helper method used when value to serialize is {@link Closeable} and its <code>close()</code> * method is to be called right after serialization has been called */ private final void _writeCloseableValue(JsonGenerator jgen, Object value, SerializationConfig cfg) throws IOException, JsonGenerationException, JsonMappingException { Closeable toClose = (Closeable) value; try { if (_rootType == null) { _serializerProvider(cfg).serializeValue(jgen, value); } else { _serializerProvider(cfg).serializeValue(j

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>gen, value, _rootType, _rootSerializer); } if (_config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } Closeable tmpToClose = toClose; toClose = null; tmpToClose.close(); } finally { if (toClose != null) { try { toClose.close(); } catch (IOException ioe) { } } } } /** * Method called to locate (root) serializer ahead of time, if permitted * by configuration. Method also is NOT to throw an exception if * access fails. */ protected JsonSerializer<Object> _prefetchRootSerializer( SerializationConfig config, JavaType valueType) { if (valueType == null || !_config.isEnabled(SerializationFeature.EAGER_SERIALIZER_FETCH)) { return null; } try { return _serializerProvider(config).findTypedValueSerializer(valueType, true, null); } catch (JsonProcessingException e) { // need to swallow? return null; } } /** * Helper method called to set or override settings of passed-in * {@link JsonGenerator} * * @since 2.1 */ private void _configureJsonGenerator(JsonGenerator jgen) { if (_prettyPrinter != null) { PrettyPrinter pp = _prettyPrinter; if (pp == NULL_PRETTY_PRINTER) { jgen.setPrettyPrinter(null); } else { /* [JACKSON-851]: Better take care of stateful PrettyPrinters... * like the DefaultPrettyPrinter. */ if (pp instanceof Instantiatable<?>) { pp = (PrettyPrinter) ((Instantiatable<?>) pp).createInstance(); } jgen.setPrettyPrinter(pp); } } else if (_config.isEnabled(SerializationFeature.INDENT_OUTPUT)) { jgen.useDefaultPrettyPrinter(); } if (_characterEscapes != null) { jgen.setCharacterEscapes(_characterEscapes); } // [JACKSON-520]: add support for pass-through schema: if (_schema != null) { jgen.setSchema(_schema); } if (_cfgBigDecimalAsPlain) { // should only set

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.lang.reflect.Type; import java.util.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; /** * Intermediate base class for Lists, Collections and Arrays * that contain static (non-dynamic) value types. */ public abstract class StaticListSerializerBase<T extends Collection<?>> extends StdSerializer<T> { protected StaticListSerializerBase(Class<?> cls) { super(cls, false); } @Override public boolean isEmpty(T value) { return (value == null) || (value.size() == 0); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("array", true).set("items", contentSchema()); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { acceptContentVisitor(visitor.expectArrayFormat(typeHint)); } /* /********************************************************** /* Abstract methods for sub-classes to implement /********************************************************** */ protected abstract JsonNode contentSchema(); protected abstract void acceptContentVisitor(JsonArrayFormatVisitor visitor) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>) throws JsonMappingException { ExternalTypeHandler.Builder extTypes = null; // if ValueInstantiator can use "creator" approach, need to resolve it here... if (_valueInstantiator.canCreateFromObjectWith()) { SettableBeanProperty[] creatorProps = _valueInstantiator.getFromObjectArguments(ctxt.getConfig()); _propertyBasedCreator = PropertyBasedCreator.construct(ctxt, _valueInstantiator, creatorProps); // also: need to try to resolve 'external' type ids... for (SettableBeanProperty prop : _propertyBasedCreator.properties()) { if (prop.hasValueTypeDeserializer()) { TypeDeserializer typeDeser = prop.getValueTypeDeserializer(); if (typeDeser.getTypeInclusion() == JsonTypeInfo.As.EXTERNAL_PROPERTY) { if (extTypes == null) { extTypes = new ExternalTypeHandler.Builder(); } extTypes.addExternal(prop, typeDeser); } } } } UnwrappedPropertyHandler unwrapped = null; for (SettableBeanProperty origProp : _beanProperties) { SettableBeanProperty prop = origProp; // May already have deserializer from annotations, if so, skip: if (!prop.hasValueDeserializer()) { // [Issue#125]: allow use of converters JsonDeserializer<?> deser = findConvertingDeserializer(ctxt, prop); if (deser == null) { deser = findDeserializer(ctxt, prop.getType(), prop); } prop = prop.withValueDeserializer(deser); } else { // may need contextual version JsonDeserializer<Object> deser = prop.getValueDeserializer(); /* Important! This is the only place where actually handle "primary" * property deserializers -- call is different from other places. */ JsonDeserializer<?> cd = ctxt.handlePrimaryContextualization(deser, prop); if (cd != deser) { prop = prop.withValueDeserializer(cd); } } // [JACKSON-235]: need to link managed references with matching back references prop = _resolveManagedReferenceProperty(ctxt, prop); // issue #351: need to wrap properties that require object id resolution. if (!(prop instanceof ManagedReferenceProperty)) { prop = _resolvedObjectIdProperty(ctxt, prop

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } AnnotatedWithParams delegateCreator = _valueInstantiator.getDelegateCreator(); // Need to create a temporary property to allow contextual deserializers: BeanProperty.Std property = new BeanProperty.Std(TEMP_PROPERTY_NAME, delegateType, null, _classAnnotations, delegateCreator, PropertyMetadata.STD_OPTIONAL); _delegateDeserializer = findDeserializer(ctxt, delegateType, property); } if (extTypes != null) { _externalTypeIdHandler = extTypes.build(); // we consider this non-standard, to offline handling _nonStandardCreation = true; } _unwrappedPropertyHandler = unwrapped; if (unwrapped != null) { // we consider this non-standard, to offline handling _nonStandardCreation = true; } // may need to disable vanilla processing, if unwrapped handling was enabled... _vanillaProcessing = _vanillaProcessing && !_nonStandardCreation; } /** * Helper method that can be used to see if specified property is annotated * to indicate use of a converter for property value (in case of container types, * it is container type itself, not key or content type). * * @since 2.2 */ protected JsonDeserializer<Object> findConvertingDeserializer(DeserializationContext ctxt, SettableBeanProperty prop) throws JsonMappingException { final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); if (intr != null) { Object convDef = intr.findDeserializationConverter(prop.getMember()); if (convDef != null) { Converter<Object,Object> conv = ctxt.converterInstance(prop.getMember(), convDef); JavaType delegateType = conv.getInputType(ctxt.getTypeFactory()); JsonDeserializer<?> ser = ctxt.findContextualValueDeserializer(delegateType, prop); return new StdDelegatingDeserializer<Object>(conv, delegateType, ser); } } return null; } /** * Although most of post-processing is done in resolve(), we only get * access to referring property's annotations here; and this is needed * to support per-property ObjectIds. * We will also consider Shape transformations (read from Array) at this * point, since it may come from either Class definition or property. */ @Override public Json

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Deserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { ObjectIdReader oir = _objectIdReader; // First: may have an override for Object Id: final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); final AnnotatedMember accessor = (property == null || intr == null) ? null : property.getMember(); if (accessor != null && intr != null) { ObjectIdInfo objectIdInfo = intr.findObjectIdInfo(accessor); if (objectIdInfo != null) { // some code duplication here as well (from BeanDeserializerFactory) // 2.1: allow modifications by "id ref" annotations as well: objectIdInfo = intr.findObjectReferenceInfo(accessor, objectIdInfo); Class<?> implClass = objectIdInfo.getGeneratorType(); // Property-based generator is trickier JavaType idType; SettableBeanProperty idProp; ObjectIdGenerator<?> idGen; ObjectIdResolver resolver = ctxt.objectIdResolverInstance(accessor, objectIdInfo); if (implClass == ObjectIdGenerators.PropertyGenerator.class) { PropertyName propName = objectIdInfo.getPropertyName(); idProp = findProperty(propName); if (idProp == null) { throw new IllegalArgumentException("Invalid Object Id definition for " +handledType().getName()+": can not find property with name '"+propName+"'"); } idType = idProp.getType(); idGen = new PropertyBasedObjectIdGenerator(objectIdInfo.getScope()); } else { // other types need to be simpler JavaType type = ctxt.constructType(implClass); idType = ctxt.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0]; idProp = null; idGen = ctxt.objectIdGeneratorInstance(accessor, objectIdInfo); } JsonDeserializer<?> deser = ctxt.findRootValueDeserializer(idType); oir = ObjectIdReader.construct(idType, objectIdInfo.getPropertyName(), idGen, deser, idProp, resolver); } } // either way, need to resolve serializer: BeanDeserializerBase contextual = this; if (oir != null && oir != _objectIdReader) { contextual = contextual.withObjectIdReader(oir); } //

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>(jp, ctxt)); } if (_propertyBasedCreator != null) { return _deserializeUsingPropertyBased(jp, ctxt); } // should only occur for abstract types... if (_beanType.isAbstract()) { throw JsonMappingException.from(jp, "Can not instantiate abstract type "+_beanType +" (need to add/enable type information?)"); } throw JsonMappingException.from(jp, "No suitable constructor found for type " +_beanType+": can not instantiate from JSON object (need to add/enable type information?)"); } protected abstract Object _deserializeUsingPropertyBased(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException; @SuppressWarnings("incomplete-switch") public Object deserializeFromNumber(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // First things first: id Object Id is used, most likely that's it if (_objectIdReader != null) { return deserializeFromObjectId(jp, ctxt); } switch (jp.getNumberType()) { case INT: if (_delegateDeserializer != null) { if (!_valueInstantiator.canCreateFromInt()) { Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); if (_injectables != null) { injectValues(ctxt, bean); } return bean; } } return _valueInstantiator.createFromInt(ctxt, jp.getIntValue()); case LONG: if (_delegateDeserializer != null) { if (!_valueInstantiator.canCreateFromInt()) { Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); if (_injectables != null) { injectValues(ctxt, bean); } return bean; } } return _valueInstantiator.createFromLong(ctxt, jp.getLongValue()); } // actually, could also be BigInteger, so: if (_delegateDeserializer != null) { Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); if (_injectables != null) { injectValues(ctxt, bean); } return bean; } throw ctxt.instantiationException(getBeanClass

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>()) { Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); if (_injectables != null) { injectValues(ctxt, bean); } return bean; } } boolean value = (jp.getCurrentToken() == JsonToken.VALUE_TRUE); return _valueInstantiator.createFromBoolean(ctxt, value); } public Object deserializeFromArray(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (_delegateDeserializer != null) { try { Object bean = _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); if (_injectables != null) { injectValues(ctxt, bean); } return bean; } catch (Exception e) { wrapInstantiationProblem(e, ctxt); } } else if (ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { jp.nextToken(); final Object value = deserialize(jp, ctxt); if (jp.nextToken() != JsonToken.END_ARRAY) { throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY, "Attempted to unwrap single value array for single '" + _valueClass.getName() + "' value but there was more than a single value in the array"); } return value; } throw ctxt.mappingException(getBeanClass()); } /* /********************************************************** /* Overridable helper methods /********************************************************** */ protected void injectValues(DeserializationContext ctxt, Object bean) throws IOException, JsonProcessingException { for (ValueInjector injector : _injectables) { injector.inject(ctxt, bean); } } /** * Method called to handle set of one or more unknown properties, * stored in their entirety in given {@link TokenBuffer} * (as field entries, name and value). */ @SuppressWarnings("resource") protected Object handleUnknownProperties(DeserializationContext ctxt, Object bean, TokenBuffer unknownTokens) throws IOException, JsonProcessingException { // First: add closing END_OBJECT as marker unknownTokens.writeEndObject(); // note: buffer does NOT have starting START_OBJECT JsonParser bufferParser = unknownTokens.asParser(); while (buffer

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Parser.nextToken() != JsonToken.END_OBJECT) { String propName = bufferParser.getCurrentName(); // Unknown: let's call handler method bufferParser.nextToken(); handleUnknownProperty(bufferParser, ctxt, bean, propName); } return bean; } /** * Helper method called for an unknown property, when using "vanilla" * processing. */ protected void handleUnknownVanilla(JsonParser jp, DeserializationContext ctxt, Object bean, String propName) throws IOException, JsonProcessingException { if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, bean, propName); } else if (_anySetter != null) { try { // should we consider return type of any setter? _anySetter.deserializeAndSet(jp, ctxt, bean, propName); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } } else { // Unknown: let's call handler method handleUnknownProperty(jp, ctxt, bean, propName); } } /** * Method called when a JSON property is encountered that has not matching * setter, any-setter or field, and thus can not be assigned. */ @Override protected void handleUnknownProperty(JsonParser jp, DeserializationContext ctxt, Object beanOrClass, String propName) throws IOException, JsonProcessingException { if (_ignoreAllUnknown) { jp.skipChildren(); return; } if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, beanOrClass, propName); } // Otherwise use default handling (call handler(s); if not // handled, throw exception or skip depending on settings) super.handleUnknownProperty(jp, ctxt, beanOrClass, propName); } /** * Method called when an explicitly ignored property (one specified with a * name to match, either by property annotation or class annotation) is encountered. * * @since 2.3 */ protected void handleIgnoredProperty(JsonParser jp, DeserializationContext ctxt, Object beanOrClass, String propName) throws IOException, JsonProcessingException {

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Buffer unknownTokens) throws IOException, JsonProcessingException { JsonDeserializer<Object> subDeser; // First: maybe we have already created sub-type deserializer? synchronized (this) { subDeser = (_subDeserializers == null) ? null : _subDeserializers.get(new ClassKey(bean.getClass())); } if (subDeser != null) { return subDeser; } // If not, maybe we can locate one. First, need provider JavaType type = ctxt.constructType(bean.getClass()); /* 30-Jan-2012, tatu: Ideally we would be passing referring * property; which in theory we could keep track of via * ResolvableDeserializer (if we absolutely must...). * But for now, let's not bother. */ // subDeser = ctxt.findValueDeserializer(type, _property); subDeser = ctxt.findRootValueDeserializer(type); // Also, need to cache it if (subDeser != null) { synchronized (this) { if (_subDeserializers == null) { _subDeserializers = new HashMap<ClassKey,JsonDeserializer<Object>>();; } _subDeserializers.put(new ClassKey(bean.getClass()), subDeser); } } return subDeser; } /* /********************************************************** /* Helper methods for error reporting /********************************************************** */ /** * Method that will modify caught exception (passed in as argument) * as necessary to include reference information, and to ensure it * is a subtype of {@link IOException}, or an unchecked exception. *<p> * Rules for wrapping and unwrapping are bit complicated; essentially: *<ul> * <li>Errors are to be passed as is (if uncovered via unwrapping) * <li>"Plain" IOExceptions (ones that are not of type * {@link JsonMappingException} are to be passed as is *</ul> */ public void wrapAndThrow(Throwable t, Object bean, String fieldName, DeserializationContext ctxt) throws IOException { // [JACKSON-55] Need to add reference information throw JsonMappingException.wrapWithPath(throwOrReturnThrowable(t, ctxt

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>), bean, fieldName); } @Deprecated // since 2.4, not used by core Jackson; only relevant for arrays/Collections public void wrapAndThrow(Throwable t, Object bean, int index, DeserializationContext ctxt) throws IOException { // [JACKSON-55] Need to add reference information throw JsonMappingException.wrapWithPath(throwOrReturnThrowable(t, ctxt), bean, index); } private Throwable throwOrReturnThrowable(Throwable t, DeserializationContext ctxt) throws IOException { /* 05-Mar-2009, tatu: But one nasty edge is when we get * StackOverflow: usually due to infinite loop. But that * often gets hidden within an InvocationTargetException... */ while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } // Errors to be passed as is if (t instanceof Error) { throw (Error) t; } boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS); // Ditto for IOExceptions; except we may want to wrap JSON exceptions if (t instanceof IOException) { if (!wrap || !(t instanceof JsonProcessingException)) { throw (IOException) t; } } else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions if (t instanceof RuntimeException) { throw (RuntimeException) t; } } return t; } protected void wrapInstantiationProblem(Throwable t, DeserializationContext ctxt) throws IOException { while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } // Errors and "plain" IOExceptions to be passed as is if (t instanceof Error) { throw (Error) t; } boolean wrap = (ctxt == null) || ctxt.isEnabled(DeserializationFeature.WRAP_EXCEPTIONS); if (t instanceof IOException) { // Since we have no more information to add, let's not actually wrap.. throw (IOException) t; } else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions if (t instanceof RuntimeException) { throw (RuntimeException) t

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>_JAVAX_XML) || hasSupertypeStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) { factoryName = SERIALIZERS_FOR_JAVAX_XML; } else if (doesImplement(rawType, CLASS_NAME_DOM_NODE)) { return (JsonSerializer<?>) instantiate(SERIALIZER_FOR_DOM_NODE); } else { return null; } Object ob = instantiate(factoryName); if (ob == null) { // could warn, if we had logging system (j.u.l?) return null; } return ((Serializers) ob).findSerializer(config, type, beanDesc); } public JsonDeserializer<?> findDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { Class<?> rawType = type.getRawClass(); String className = rawType.getName(); String factoryName; if (className.startsWith(PACKAGE_PREFIX_JAVAX_XML) || hasSupertypeStartingWith(rawType, PACKAGE_PREFIX_JAVAX_XML)) { factoryName = DESERIALIZERS_FOR_JAVAX_XML; } else if (doesImplement(rawType, CLASS_NAME_DOM_DOCUMENT)) { return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_DOCUMENT); } else if (doesImplement(rawType, CLASS_NAME_DOM_NODE)) { return (JsonDeserializer<?>) instantiate(DESERIALIZER_FOR_DOM_NODE); } else { return null; } Object ob = instantiate(factoryName); if (ob == null) { // could warn, if we had logging system (j.u.l?) return null; } return ((Deserializers) ob).findBeanDeserializer(type, config, beanDesc); } /* /********************************************************** /* Internal helper methods /********************************************************** */ private Object instantiate(String className) { try { return Class.forName(className).newInstance(); } catch (LinkageError e) { } // too many different kinds to enumerate here: catch (Exception e) { } return null; } private boolean doesImplement(Class<?> actualType, String classNameToImplement) { for (

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } /* /********************************************************** /* Access to Object Id aspects /********************************************************** */ /** * Method called to find the Object Id for given POJO, if one * has been generated. Will always return a non-null Object; * contents vary depending on whether an Object Id already * exists or not. */ public abstract WritableObjectId findObjectId(Object forPojo, ObjectIdGenerator<?> generatorType); /* /********************************************************** /* General serializer locating functionality /********************************************************** */ /** * Method called to get hold of a serializer for a value of given type; * or if no such serializer can be found, a default handler (which * may do a best-effort generic serialization or just simply * throw an exception when invoked). *<p> * Note: this method is only called for non-null values; not for keys * or null values. For these, check out other accessor methods. *<p> * Note that starting with version 1.5, serializers should also be type-aware * if they handle polymorphic types. That means that it may be necessary * to also use a {@link TypeSerializer} based on declared (static) type * being serializer (whereas actual data may be serialized using dynamic * type) * * @throws JsonMappingException if there are fatal problems with * accessing suitable serializer; including that of not * finding any serializer */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findValueSerializer(Class<?> valueType, BeanProperty property) throws JsonMappingException { // Fast lookup from local lookup thingy works? JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { // If not, maybe shared map already has it? ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { // ... possibly as fully typed? ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType)); if (ser == null) { // If neither, must create ser = _createAndCacheUntypedSerializer(valueType); // Not found? Must use the unknown type serializer /* Couldn't create? Need to return the fallback serializer, which * most likely will report

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> an error: but one question is whether * we should cache it? */ if (ser == null) { ser = getUnknownTypeSerializer(valueType); // Should this be added to lookups? if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } } // at this point, resolution has occured, but not contextualization return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property); } /** * Similar to {@link #findValueSerializer(Class,BeanProperty)}, but takes * full generics-aware type instead of raw class. * This is necessary for accurate handling of external type information, * to handle polymorphic types. * * @param property When creating secondary serializers, property for which * serializer is needed: annotations of the property (or bean that contains it) * may be checked to create contextual serializers. */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findValueSerializer(JavaType valueType, BeanProperty property) throws JsonMappingException { // Fast lookup from local lookup thingy works? JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { // If not, maybe shared map already has it? ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { // If neither, must create ser = _createAndCacheUntypedSerializer(valueType); // Not found? Must use the unknown type serializer /* Couldn't create? Need to return the fallback serializer, which * most likely will report an error: but one question is whether * we should cache it? */ if (ser == null) { ser = getUnknownTypeSerializer(valueType.getRawClass()); // Should this be added to lookups? if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property); } /** * Similar to {@link #findValueSerializer(JavaType, BeanProperty)}, but

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> used * when finding "primary" property value serializer (one directly handling * value of the property). Difference has to do with contextual resolution, * and method(s) called: this method should only be called when caller is * certain that this is the primary property value serializer. * * @param property Property that is being handled; will never be null, and its * type has to match <code>valueType</code> parameter. * * @since 2.3 */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findPrimaryPropertySerializer(JavaType valueType, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType.getRawClass()); // Should this be added to lookups? if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } return (JsonSerializer<Object>) handlePrimaryContextualization(ser, property); } /** * @since 2.3 */ @SuppressWarnings("unchecked") public JsonSerializer<Object> findPrimaryPropertySerializer(Class<?> valueType, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(valueType); if (ser == null) { ser = _serializerCache.untypedValueSerializer(_config.constructType(valueType)); if (ser == null) { ser = _createAndCacheUntypedSerializer(valueType); if (ser == null) { ser = getUnknownTypeSerializer(valueType); if (CACHE_UNKNOWN_MAPPINGS) { _serializerCache.addAndResolveNonTypedSerializer(valueType, ser, this); } return ser; } } } } return (JsonSerializer<Object>) handlePrimaryContextualization(ser,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> property); } /** * Method called to locate regular serializer, matching type serializer, * and if both found, wrap them in a serializer that calls both in correct * sequence. This method is currently only used for root-level serializer * handling to allow for simpler caching. A call can always be replaced * by equivalent calls to access serializer and type serializer separately. * * @param valueType Type for purpose of locating a serializer; usually dynamic * runtime type, but can also be static declared type, depending on configuration * @param cache Whether resulting value serializer should be cached or not; this is just * a hint * @param property When creating secondary serializers, property for which * serializer is needed: annotations of the property (or bean that contains it) * may be checked to create contextual serializers. */ public JsonSerializer<Object> findTypedValueSerializer(Class<?> valueType, boolean cache, BeanProperty property) throws JsonMappingException { // Two-phase lookups; local non-shared cache, then shared: JsonSerializer<Object> ser = _knownSerializers.typedValueSerializer(valueType); if (ser != null) { return ser; } // If not, maybe shared map already has it? ser = _serializerCache.typedValueSerializer(valueType); if (ser != null) { return ser; } // Well, let's just compose from pieces: ser = findValueSerializer(valueType, property); TypeSerializer typeSer = _serializerFactory.createTypeSerializer(_config, _config.constructType(valueType)); if (typeSer != null) { typeSer = typeSer.forProperty(property); ser = new TypeWrappedSerializer(typeSer, ser); } if (cache) { _serializerCache.addTypedSerializer(valueType, ser); } return ser; } /** * Method called to locate regular serializer, matching type serializer, * and if both found, wrap them in a serializer that calls both in correct * sequence. This method is currently only used for root-level serializer * handling to allow for simpler caching. A call can always be replaced * by equivalent calls to access serializer and type serializer separately. * * @param valueType Declared type of value being serialized (which may not *

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> be actual runtime type); used for finding both value serializer and * type serializer to use for adding polymorphic type (if any) * @param cache Whether resulting value serializer should be cached or not; this is just * a hint * @param property When creating secondary serializers, property for which * serializer is needed: annotations of the property (or bean that contains it) * may be checked to create contextual serializers. */ public JsonSerializer<Object> findTypedValueSerializer(JavaType valueType, boolean cache, BeanProperty property) throws JsonMappingException { // Two-phase lookups; local non-shared cache, then shared: JsonSerializer<Object> ser = _knownSerializers.typedValueSerializer(valueType); if (ser != null) { return ser; } // If not, maybe shared map already has it? ser = _serializerCache.typedValueSerializer(valueType); if (ser != null) { return ser; } // Well, let's just compose from pieces: ser = findValueSerializer(valueType, property); TypeSerializer typeSer = _serializerFactory.createTypeSerializer(_config, valueType); if (typeSer != null) { typeSer = typeSer.forProperty(property); ser = new TypeWrappedSerializer(typeSer, ser); } if (cache) { _serializerCache.addTypedSerializer(valueType, ser); } return ser; } /** * Method called to get the serializer to use for serializing * non-null Map keys. Separation from regular * {@link #findValueSerializer} method is because actual write * method must be different (@link JsonGenerator#writeFieldName}; * but also since behavior for some key types may differ. *<p> * Note that the serializer itself can be called with instances * of any Java object, but not nulls. */ public JsonSerializer<Object> findKeySerializer(JavaType keyType, BeanProperty property) throws JsonMappingException { JsonSerializer<Object> ser = _serializerFactory.createKeySerializer(_config, keyType, _keySerializer); // 25-Feb-2011, tatu: As per [JACKSON-519], need to ensure contextuality works here, too return _

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>handleContextualResolvable(ser, property); } /* /******************************************************** /* Accessors for specialized serializers /******************************************************** */ /** * @since 2.0 */ public JsonSerializer<Object> getDefaultNullKeySerializer() { return _nullKeySerializer; } /** * @since 2.0 */ public JsonSerializer<Object> getDefaultNullValueSerializer() { return _nullValueSerializer; } /** * Method called to get the serializer to use for serializing * Map keys that are nulls: this is needed since JSON does not allow * any non-String value as key, including null. *<p> * Typically, returned serializer * will either throw an exception, or use an empty String; but * other behaviors are possible. */ /** * Method called to find a serializer to use for null values for given * declared type. Note that type is completely based on declared type, * since nulls in Java have no type and thus runtime type can not be * determined. * * @since 2.0 */ public JsonSerializer<Object> findNullKeySerializer(JavaType serializationType, BeanProperty property) throws JsonMappingException { return _nullKeySerializer; } /** * Method called to get the serializer to use for serializing null * values for specified property. *<p> * Default implementation simply calls {@link #getDefaultNullValueSerializer()}; * can be overridden to add custom null serialization for properties * of certain type or name. This gives method full granularity to basically * override null handling for any specific property or class of properties. * * @since 2.0 */ public JsonSerializer<Object> findNullValueSerializer(BeanProperty property) throws JsonMappingException { return _nullValueSerializer; } /** * Method called to get the serializer to use if provider * can not determine an actual type-specific serializer * to use; typically when none of {@link SerializerFactory} * instances are able to construct a serializer. *<p> * Typically, returned serializer will throw an exception, * although alternatively {@link com.fasterxml.jackson.databind.ser.std.ToStringSerializer} * could be returned as well. * * @param unknownType Type for which no serializer is found

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> */ public JsonSerializer<Object> getUnknownTypeSerializer(Class<?> unknownType) { return _unknownTypeSerializer; } /* /********************************************************** /* Methods for creating instances based on annotations /********************************************************** */ /** * Method that can be called to construct and configure serializer instance, * either given a {@link Class} to instantiate (with default constructor), * or an uninitialized serializer instance. * Either way, serialize will be properly resolved * (via {@link com.fasterxml.jackson.databind.ser.ResolvableSerializer}) and/or contextualized * (via {@link com.fasterxml.jackson.databind.ser.ContextualSerializer}) as necessary. * * @param annotated Annotated entity that contained definition * @param serDef Serializer definition: either an instance or class */ public abstract JsonSerializer<Object> serializerInstance(Annotated annotated, Object serDef) throws JsonMappingException; /* /********************************************************** /* Support for contextualization /********************************************************** */ /** * @deprecated Since 2.3 (and to be removed from 2.4); use * {@link #handlePrimaryContextualization} or {@link #handleSecondaryContextualization} * instead */ @Deprecated public JsonSerializer<?> handleContextualization(JsonSerializer<?> ser, BeanProperty property) throws JsonMappingException { return handleSecondaryContextualization(ser, property); } /** * Method called for primary property serializers (ones * directly created to serialize values of a POJO property), * to handle details of resolving * {@link ContextualSerializer} with given property context. * * @param property Property for which the given primary serializer is used; never null. * * @since 2.3 */ public JsonSerializer<?> handlePrimaryContextualization(JsonSerializer<?> ser, BeanProperty property) throws JsonMappingException { if (ser != null) { if (ser instanceof ContextualSerializer) { ser = ((ContextualSerializer) ser).createContextual(this, property); } } return ser; } /** * Method called for secondary property serializers (ones * NOT directly created to serialize values of a POJO property * but instead created as a dependant serializer -- such as value serializers * for structured

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> types, or serializers for root values) * to handle details of resolving * {@link ContextualDeserializer} with given property context. * Given that these serializers are not directly related to given property * (or, in case of root value property, to any property), annotations * accessible may or may not be relevant. * * @param property Property for which serializer is used, if any; null * when deserializing root values * * @since 2.3 */ public JsonSerializer<?> handleSecondaryContextualization(JsonSerializer<?> ser, BeanProperty property) throws JsonMappingException { if (ser != null) { if (ser instanceof ContextualSerializer) { ser = ((ContextualSerializer) ser).createContextual(this, property); } } return ser; } /* /******************************************************** /* Convenience methods /******************************************************** */ /** * Convenience method that will serialize given value (which can be * null) using standard serializer locating functionality. It can * be called for all values including field and Map values, but usually * field values are best handled calling * {@link #defaultSerializeField} instead. */ public final void defaultSerializeValue(Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { if (value == null) { if (_stdNullValueSerializer) { // minor perf optimization jgen.writeNull(); } else { _nullValueSerializer.serialize(null, jgen, this); } } else { Class<?> cls = value.getClass(); findTypedValueSerializer(cls, true, null).serialize(value, jgen, this); } } /** * Convenience method that will serialize given field with specified * value. Value may be null. Serializer is done using the usual * null) using standard serializer locating functionality. */ public final void defaultSerializeField(String fieldName, Object value, JsonGenerator jgen) throws IOException, JsonProcessingException { jgen.writeFieldName(fieldName); if (value == null) { /* Note: can't easily check for suppression at this point * any more; caller must check it. */ if (_stdNullValueSerializer) { // minor perf optimization jgen.writeNull(); } else { _nullValueSerializer.serialize(

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>valueOf(timestamp)); } else { jgen.writeFieldName(_dateFormat().format(new Date(timestamp))); } } /** * Method that will handle serialization of Dates used as {@link java.util.Map} keys, * based on {@link SerializationFeature#WRITE_DATE_KEYS_AS_TIMESTAMPS} * value (and if using textual representation, configured date format) */ public void defaultSerializeDateKey(Date date, JsonGenerator jgen) throws IOException, JsonProcessingException { if (isEnabled(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS)) { jgen.writeFieldName(String.valueOf(date.getTime())); } else { jgen.writeFieldName(_dateFormat().format(date)); } } public final void defaultSerializeNull(JsonGenerator jgen) throws IOException, JsonProcessingException { if (_stdNullValueSerializer) { // minor perf optimization jgen.writeNull(); } else { _nullValueSerializer.serialize(null, jgen, this); } } /* /******************************************************** /* Helper methods /******************************************************** */ protected void _reportIncompatibleRootType(Object value, JavaType rootType) throws IOException, JsonProcessingException { /* 07-Jan-2010, tatu: As per [JACKSON-456] better handle distinction between wrapper types, * primitives */ if (rootType.isPrimitive()) { Class<?> wrapperType = ClassUtil.wrapperType(rootType.getRawClass()); // If it's just difference between wrapper, primitive, let it slide if (wrapperType.isAssignableFrom(value.getClass())) { return; } } throw new JsonMappingException("Incompatible types: declared root type ("+rootType+") vs " +value.getClass().getName()); } /** * Method that will try to find a serializer, either from cache * or by constructing one; but will not return an "unknown" serializer * if this can not be done but rather returns null. * * @return Serializer if one can be found, null if not. */ protected JsonSerializer<Object> _findExplicitUntypedSerializer(Class<?> runtimeType) throws JsonMappingException { // Fast lookup from local lookup

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> thingy works? JsonSerializer<Object> ser = _knownSerializers.untypedValueSerializer(runtimeType); if (ser != null) { return ser; } // If not, maybe shared map already has it? ser = _serializerCache.untypedValueSerializer(runtimeType); if (ser != null) { return ser; } return _createAndCacheUntypedSerializer(runtimeType); } /* /********************************************************** /* Low-level methods for actually constructing and initializing /* serializers /********************************************************** */ /** * Method that will try to construct a value serializer; and if * one is successfully created, cache it for reuse. */ protected JsonSerializer<Object> _createAndCacheUntypedSerializer(Class<?> type) throws JsonMappingException { JsonSerializer<Object> ser; try { ser = _createUntypedSerializer(_config.constructType(type)); } catch (IllegalArgumentException iae) { /* We better only expose checked exceptions, since those * are what caller is expected to handle */ throw new JsonMappingException(iae.getMessage(), null, iae); } if (ser != null) { _serializerCache.addAndResolveNonTypedSerializer(type, ser, this); } return ser; } protected JsonSerializer<Object> _createAndCacheUntypedSerializer(JavaType type) throws JsonMappingException { JsonSerializer<Object> ser; try { ser = _createUntypedSerializer(type); } catch (IllegalArgumentException iae) { /* We better only expose checked exceptions, since those * are what caller is expected to handle */ throw new JsonMappingException(iae.getMessage(), null, iae); } if (ser != null) { _serializerCache.addAndResolveNonTypedSerializer(type, ser, this); } return ser; } /** * @since 2.1 */ protected JsonSerializer<Object> _createUntypedSerializer(JavaType type) throws JsonMappingException { // 17-Feb-2013, tatu: Used to call deprecated method (that passed property) return (JsonSerializer<Object>)_serializerFactory.createSerializer(this, type); } /** * Helper method called to resolve and contextual

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>ize given * serializer, if and as necessary. */ @SuppressWarnings("unchecked") protected JsonSerializer<Object> _handleContextualResolvable(JsonSerializer<?> ser, BeanProperty property) throws JsonMappingException { if (ser instanceof ResolvableSerializer) { ((ResolvableSerializer) ser).resolve(this); } return (JsonSerializer<Object>) handleSecondaryContextualization(ser, property); } @SuppressWarnings("unchecked") protected JsonSerializer<Object> _handleResolvable(JsonSerializer<?> ser) throws JsonMappingException { if (ser instanceof ResolvableSerializer) { ((ResolvableSerializer) ser).resolve(this); } return (JsonSerializer<Object>) ser; } /* /********************************************************** /* Internal methods /********************************************************** */ protected final DateFormat _dateFormat() { if (_dateFormat != null) { return _dateFormat; } /* 24-Feb-2012, tatu: At this point, all timezone configuration * should have occured, with respect to default dateformat * and timezone configuration. But we still better clone * an instance as formatters may be stateful. */ DateFormat df = _config.getDateFormat(); _dateFormat = df = (DateFormat) df.clone(); return df; } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> || ignorable.length == 0) ? null : ArrayBuilders.arrayToSet(ignorable); } /* /********************************************************** /* Validation, post-processing (ResolvableDeserializer) /********************************************************** */ @Override public void resolve(DeserializationContext ctxt) throws JsonMappingException { // May need to resolve types for delegate- and/or property-based creators: if (_valueInstantiator.canCreateUsingDelegate()) { JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig()); if (delegateType == null) { throw new IllegalArgumentException("Invalid delegate-creator definition for "+_mapType +": value instantiator ("+_valueInstantiator.getClass().getName() +") returned true for 'canCreateUsingDelegate()', but null for 'getDelegateType()'"); } /* Theoretically should be able to get CreatorProperty for delegate * parameter to pass; but things get tricky because DelegateCreator * may contain injectable values. So, for now, let's pass nothing. */ _delegateDeserializer = findDeserializer(ctxt, delegateType, null); } if (_valueInstantiator.canCreateFromObjectWith()) { SettableBeanProperty[] creatorProps = _valueInstantiator.getFromObjectArguments(ctxt.getConfig()); _propertyBasedCreator = PropertyBasedCreator.construct(ctxt, _valueInstantiator, creatorProps); } _standardStringKey = _isStdKeyDeser(_mapType, _keyDeserializer); } /** * Method called to finalize setup of this deserializer, * when it is known for which property deserializer is needed for. */ @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { KeyDeserializer kd = _keyDeserializer; if (kd == null) { kd = ctxt.findKeyDeserializer(_mapType.getKeyType(), property); } else { if (kd instanceof ContextualKeyDeserializer) { kd = ((ContextualKeyDeserializer) kd).createContextual(ctxt, property); } } JsonDeserializer<?> vd = _valueDeserializer; // #125: May have a content converter vd = findConvertingContentDeserializer(ctxt, property, vd); if (vd == null) { vd

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> prop = creator.findCreatorProperty(propName); if (prop != null) { // Last property to set? Object value = prop.deserialize(jp, ctxt); if (buffer.assignParameter(prop.getCreatorIndex(), value)) { jp.nextToken(); Map<Object,Object> result; try { result = (Map<Object,Object>)creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _mapType.getRawClass()); return null; } _readAndBind(jp, ctxt, result); return result; } continue; } // other property? needs buffering String fieldName = jp.getCurrentName(); Object key = _keyDeserializer.deserializeKey(fieldName, ctxt); Object value; if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(); } else if (typeDeser == null) { value = valueDes.deserialize(jp, ctxt); } else { value = valueDes.deserializeWithType(jp, ctxt, typeDeser); } buffer.bufferMapProperty(key, value); } // end of JSON object? // if so, can just construct and leave... try { return (Map<Object,Object>)creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _mapType.getRawClass()); return null; } } // note: copied from BeanDeserializer; should try to share somehow... protected void wrapAndThrow(Throwable t, Object ref) throws IOException { // to handle StackOverflow: while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } // Errors and "plain" IOExceptions to be passed as is if (t instanceof Error) { throw (Error) t; } // ... except for mapping exceptions if (t instanceof IOException && !(t instanceof JsonMappingException)) { throw (IOException) t; } throw JsonMappingException.wrapWithPath(t, ref, null); } private void handleUnresolvedReference(JsonParser jp, MapReferringAccumulator accumulator, Object key, UnresolvedForwardReference reference) throws JsonMappingException {

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> if (accumulator == null) { throw JsonMappingException.from(jp, "Unresolved forward reference but no identity info.", reference); } Referring referring = accumulator.handleUnresolvedReference(reference, key); reference.getRoid().appendReferring(referring); } private final static class MapReferringAccumulator { private final Class<?> _valueType; private Map<Object,Object> _result; /** * A list of {@link MapReferring} to maintain ordering. */ private List<MapReferring> _accumulator = new ArrayList<MapReferring>(); public MapReferringAccumulator(Class<?> valueType, Map<Object, Object> result) { _valueType = valueType; _result = result; } public void put(Object key, Object value) { if (_accumulator.isEmpty()) { _result.put(key, value); } else { MapReferring ref = _accumulator.get(_accumulator.size() - 1); ref.next.put(key, value); } } public Referring handleUnresolvedReference(UnresolvedForwardReference reference, Object key) { MapReferring id = new MapReferring(this, reference, _valueType, key); _accumulator.add(id); return id; } public void resolveForwardReference(Object id, Object value) throws IOException { Iterator<MapReferring> iterator = _accumulator.iterator(); // Resolve ordering after resolution of an id. This means either: // 1- adding to the result map in case of the first unresolved id. // 2- merge the content of the resolved id with its previous unresolved id. Map<Object,Object> previous = _result; while (iterator.hasNext()) { MapReferring ref = iterator.next(); if (ref.hasId(id)) { iterator.remove(); previous.put(ref.key, value); previous.putAll(ref.next); return; } previous = ref.next; } throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id + "] that wasn't previously seen as unresolved."); } } /** * Helper class to maintain processing order of value. The resolved * object associated with {@link #_

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.impl; import java.io.IOException; import java.util.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.introspect.AnnotatedMember; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import com.fasterxml.jackson.databind.ser.ContextualSerializer; import com.fasterxml.jackson.databind.ser.std.StaticListSerializerBase; /** * Efficient implement for serializing {@link List}s that contains Strings and are random-accessible. * The only complexity is due to possibility that serializer for {@link String} * may be overridde; because of this, logic is needed to ensure that the default * serializer is in use to use fastest mode, or if not, to defer to custom * String serializer. */ @JacksonStdImpl public final class IndexedStringListSerializer extends StaticListSerializerBase<List<String>> implements ContextualSerializer { public final static IndexedStringListSerializer instance = new IndexedStringListSerializer(); protected final JsonSerializer<String> _serializer; /* /********************************************************** /* Life-cycle /********************************************************** */ protected IndexedStringListSerializer() { this(null); } @SuppressWarnings("unchecked") public IndexedStringListSerializer(JsonSerializer<?> ser) { super(List.class); _serializer = (JsonSerializer<String>) ser; } @Override protected JsonNode contentSchema() { return createSchemaNode("string", true); } @Override protected void acceptContentVisitor(JsonArrayFormatVisitor visitor) throws JsonMappingException { visitor.itemsFormat(JsonFormatTypes.STRING); } /* /********************************************************** /* Post-processing /********************************************************** */ @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { /* 29-Sep-2012, tatu: Actually, we need to do much more contextual *

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Custom(value, jgen, provider, 1); } } @Override public void serializeWithType(List<String> value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException { final int len = value.size(); typeSer.writeTypePrefixForArray(value, jgen); if (_serializer == null) { serializeContents(value, jgen, provider, len); } else { serializeUsingCustom(value, jgen, provider, len); } typeSer.writeTypeSuffixForArray(value, jgen); } private final void serializeContents(List<String> value, JsonGenerator jgen, SerializerProvider provider, int len) throws IOException { int i = 0; try { for (; i < len; ++i) { String str = value.get(i); if (str == null) { provider.defaultSerializeNull(jgen); } else { jgen.writeString(str); } } } catch (Exception e) { wrapAndThrow(provider, e, value, i); } } private final void serializeUsingCustom(List<String> value, JsonGenerator jgen, SerializerProvider provider, int len) throws IOException { int i = 0; try { final JsonSerializer<String> ser = _serializer; for (i = 0; i < len; ++i) { String str = value.get(i); if (str == null) { provider.defaultSerializeNull(jgen); } else { ser.serialize(str, jgen, provider); } } } catch (Exception e) { wrapAndThrow(provider, e, value, i); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.impl; import java.io.IOException; import java.util.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.introspect.AnnotatedMember; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonArrayFormatVisitor; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import com.fasterxml.jackson.databind.ser.ContextualSerializer; import com.fasterxml.jackson.databind.ser.std.StaticListSerializerBase; /** * Efficient implement for serializing {@link Collection}s that contain Strings. * The only complexity is due to possibility that serializer for {@link String} * may be overridde; because of this, logic is needed to ensure that the default * serializer is in use to use fastest mode, or if not, to defer to custom * String serializer. */ @JacksonStdImpl public class StringCollectionSerializer extends StaticListSerializerBase<Collection<String>> implements ContextualSerializer { public final static StringCollectionSerializer instance = new StringCollectionSerializer(); protected final JsonSerializer<String> _serializer; /* /********************************************************** /* Life-cycle /********************************************************** */ protected StringCollectionSerializer() { this(null); } @SuppressWarnings("unchecked") protected StringCollectionSerializer(JsonSerializer<?> ser) { super(Collection.class); _serializer = (JsonSerializer<String>) ser; } @Override protected JsonNode contentSchema() { return createSchemaNode("string", true); } @Override protected void acceptContentVisitor(JsonArrayFormatVisitor visitor) throws JsonMappingException { visitor.itemsFormat(JsonFormatTypes.STRING); } /* /********************************************************** /* Post-processing /********************************************************** */ @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { /* 29-Sep-2012, tatu: Actually, we need to do much more contextual * checking here

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>, provider); } } @Override public void serializeWithType(Collection<String> value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonGenerationException { typeSer.writeTypePrefixForArray(value, jgen); if (_serializer == null) { serializeContents(value, jgen, provider); } else { serializeUsingCustom(value, jgen, provider); } typeSer.writeTypeSuffixForArray(value, jgen); } private final void serializeContents(Collection<String> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { if (_serializer != null) { serializeUsingCustom(value, jgen, provider); return; } int i = 0; for (String str : value) { try { if (str == null) { provider.defaultSerializeNull(jgen); } else { jgen.writeString(str); } ++i; } catch (Exception e) { wrapAndThrow(provider, e, value, i); } } } private void serializeUsingCustom(Collection<String> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { final JsonSerializer<String> ser = _serializer; int i = 0; for (String str : value) { try { if (str == null) { provider.defaultSerializeNull(jgen); } else { ser.serialize(str, jgen, provider); } } catch (Exception e) { wrapAndThrow(provider, e, value, i); } } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>) { return new MethodProperty(this, deser); } /* /********************************************************** /* BeanProperty impl /********************************************************** */ @Override public <A extends Annotation> A getAnnotation(Class<A> acls) { return _annotated.getAnnotation(acls); } @Override public AnnotatedMember getMember() { return _annotated; } /* /********************************************************** /* Overridden methods /********************************************************** */ @Override public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException, JsonProcessingException { set(instance, deserialize(jp, ctxt)); } @Override public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException { return setAndReturn(instance, deserialize(jp, ctxt)); } @Override public final void set(Object instance, Object value) throws IOException { try { _setter.invoke(instance, value); } catch (Exception e) { _throwAsIOE(e, value); } } @Override public Object setAndReturn(Object instance, Object value) throws IOException { try { Object result = _setter.invoke(instance, value); return (result == null) ? instance : result; } catch (Exception e) { _throwAsIOE(e, value); return null; } } /* /********************************************************** /* JDK serialization handling /********************************************************** */ Object readResolve() { return new MethodProperty(this, _annotated.getAnnotated()); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> _buildMethod = src._buildMethod; } protected BuilderBasedDeserializer(BuilderBasedDeserializer src, NameTransformer unwrapper) { super(src, unwrapper); _buildMethod = src._buildMethod; } public BuilderBasedDeserializer(BuilderBasedDeserializer src, ObjectIdReader oir) { super(src, oir); _buildMethod = src._buildMethod; } public BuilderBasedDeserializer(BuilderBasedDeserializer src, HashSet<String> ignorableProps) { super(src, ignorableProps); _buildMethod = src._buildMethod; } @Override public JsonDeserializer<Object> unwrappingDeserializer(NameTransformer unwrapper) { /* main thing really is to just enforce ignoring of unknown * properties; since there may be multiple unwrapped values * and properties for all may be interleaved... */ return new BuilderBasedDeserializer(this, unwrapper); } @Override public BuilderBasedDeserializer withObjectIdReader(ObjectIdReader oir) { return new BuilderBasedDeserializer(this, oir); } @Override public BuilderBasedDeserializer withIgnorableProperties(HashSet<String> ignorableProps) { return new BuilderBasedDeserializer(this, ignorableProps); } @Override protected BeanAsArrayBuilderDeserializer asArrayDeserializer() { SettableBeanProperty[] props = _beanProperties.getPropertiesInInsertionOrder(); return new BeanAsArrayBuilderDeserializer(this, props, _buildMethod); } /* /********************************************************** /* JsonDeserializer implementation /********************************************************** */ protected final Object finishBuild(DeserializationContext ctxt, Object builder) throws IOException { try { return _buildMethod.getMember().invoke(builder); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); return null; } } /** * Main deserialization method for bean-based objects (POJOs). */ @Override public final Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { JsonToken t = jp.getCurrentToken(); // common case first: if (t == JsonToken.START_OBJECT) { t = jp.nextToken(); if (_vanillaProcessing) { return finishBuild(ctxt, vanillaDeserialize(jp, ctxt, t)); } Object builder =

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> return deserializeWithView(jp, ctxt, builder, view); } } JsonToken t = jp.getCurrentToken(); // 23-Mar-2010, tatu: In some cases, we start with full JSON object too... if (t == JsonToken.START_OBJECT) { t = jp.nextToken(); } for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); // Skip field name: jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { // normal case try { builder = prop.deserializeSetAndReturn(jp, ctxt, builder); } catch (Exception e) { wrapAndThrow(e, builder, propName, ctxt); } continue; } handleUnknownVanilla(jp, ctxt, handledType(), propName); } return builder; } /** * Streamlined version that is only used when no "special" * features are enabled. */ private final Object vanillaDeserialize(JsonParser jp, DeserializationContext ctxt, JsonToken t) throws IOException, JsonProcessingException { Object bean = _valueInstantiator.createUsingDefault(ctxt); for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) { String propName = jp.getCurrentName(); // Skip field name: jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { // normal case try { bean = prop.deserializeSetAndReturn(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } } else { handleUnknownVanilla(jp, ctxt, bean, propName); } } return bean; } /** * General version used when handling needs more advanced * features. */ @Override public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (_nonStandardCreation) { if (_unwrappedPropertyHandler != null) { return deserializeWithUnwrapped(jp, ctxt); } if (_externalTypeId

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Handler != null) { return deserializeWithExternalTypeId(jp, ctxt); } return deserializeFromObjectUsingNonDefault(jp, ctxt); } Object bean = _valueInstantiator.createUsingDefault(ctxt); if (_injectables != null) { injectValues(ctxt, bean); } if (_needViewProcesing) { Class<?> view = ctxt.getActiveView(); if (view != null) { return deserializeWithView(jp, ctxt, bean, view); } } for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) { String propName = jp.getCurrentName(); // Skip field name: jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { // normal case try { bean = prop.deserializeSetAndReturn(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } handleUnknownVanilla(jp, ctxt, bean, propName); } return bean; } /** * Method called to deserialize bean using "property-based creator": * this means that a non-default constructor or factory method is * called, and then possibly other setters. The trick is that * values for creator method need to be buffered, first; and * due to non-guaranteed ordering possibly some other properties * as well. */ @Override @SuppressWarnings("resource") protected final Object _deserializeUsingPropertyBased(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException { final PropertyBasedCreator creator = _propertyBasedCreator; PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader); // 04-Jan-2010, tatu: May need to collect unknown properties for polymorphic cases TokenBuffer unknown = null; JsonToken t = jp.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); jp.nextToken(); // to point to value // creator property? SettableBeanProperty creatorProp = creator.findCreatorProperty(propName);

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> if (creatorProp != null) { // Last creator property to set? Object value = creatorProp.deserialize(jp, ctxt); if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) { jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt); continue; // never gets here } // polymorphic? if (bean.getClass() != _beanType.getRawClass()) { return handlePolymorphic(jp, ctxt, bean, unknown); } if (unknown != null) { // nope, just extra unknown stuff... bean = handleUnknownProperties(ctxt, bean, unknown); } // or just clean? return _deserialize(jp, ctxt, bean); } continue; } // Object Id property? if (buffer.readIdProperty(propName)) { continue; } // regular property? needs buffering SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { buffer.bufferProperty(prop, prop.deserialize(jp, ctxt)); continue; } // As per [JACKSON-313], things marked as ignorable should not be // passed to any setter if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, handledType(), propName); continue; } // "any property"? if (_anySetter != null) { buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt)); continue; } // Ok then, let's collect the whole field; name and value if (unknown == null) { unknown = new TokenBuffer(jp); } unknown.writeFieldName(propName); unknown.copyCurrentStructure(jp); } // We hit END_OBJECT, so: Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); return null; // never gets here }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> if (unknown != null) { // polymorphic? if (bean.getClass() != _beanType.getRawClass()) { return handlePolymorphic(null, ctxt, bean, unknown); } // no, just some extra unknown properties return handleUnknownProperties(ctxt, bean, unknown); } return bean; } /* /********************************************************** /* Deserializing when we have to consider an active View /********************************************************** */ protected final Object deserializeWithView(JsonParser jp, DeserializationContext ctxt, Object bean, Class<?> activeView) throws IOException, JsonProcessingException { JsonToken t = jp.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); // Skip field name: jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { if (!prop.visibleInView(activeView)) { jp.skipChildren(); continue; } try { bean = prop.deserializeSetAndReturn(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } handleUnknownVanilla(jp, ctxt, bean, propName); } return bean; } /* /********************************************************** /* Handling for cases where we have "unwrapped" values /********************************************************** */ /** * Method called when there are declared "unwrapped" properties * which need special handling */ @SuppressWarnings("resource") protected Object deserializeWithUnwrapped(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (_delegateDeserializer != null) { return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); } if (_propertyBasedCreator != null) { return deserializeUsingPropertyBasedWithUnwrapped(jp, ctxt); } TokenBuffer tokens = new TokenBuffer(jp); tokens.writeStartObject(); Object bean = _valueInstantiator.createUsingDefault(ctxt); if (_injectables != null) { injectValues(ctxt, bean); } final Class<?> activeView = _needViewProcesing ? ctxt.

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>getActiveView() : null; for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) { String propName = jp.getCurrentName(); jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { // normal case if (activeView != null && !prop.visibleInView(activeView)) { jp.skipChildren(); continue; } try { bean = prop.deserializeSetAndReturn(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } // ignorable things should be ignored if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, bean, propName); continue; } // but... others should be passed to unwrapped property deserializers tokens.writeFieldName(propName); tokens.copyCurrentStructure(jp); // how about any setter? We'll get copies but... if (_anySetter != null) { try { _anySetter.deserializeAndSet(jp, ctxt, bean, propName); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } } tokens.writeEndObject(); _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens); return bean; } @SuppressWarnings("resource") protected Object deserializeWithUnwrapped(JsonParser jp, DeserializationContext ctxt, Object bean) throws IOException, JsonProcessingException { JsonToken t = jp.getCurrentToken(); if (t == JsonToken.START_OBJECT) { t = jp.nextToken(); } TokenBuffer tokens = new TokenBuffer(jp); tokens.writeStartObject(); final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null; for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); SettableBeanProperty prop = _beanProperties.find(propName); jp.nextToken(); if (prop != null) { // normal case if (activeView != null && !

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>prop.visibleInView(activeView)) { jp.skipChildren(); continue; } try { bean = prop.deserializeSetAndReturn(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, bean, propName); continue; } // but... others should be passed to unwrapped property deserializers tokens.writeFieldName(propName); tokens.copyCurrentStructure(jp); // how about any setter? We'll get copies but... if (_anySetter != null) { _anySetter.deserializeAndSet(jp, ctxt, bean, propName); } } tokens.writeEndObject(); _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens); return bean; } @SuppressWarnings("resource") protected Object deserializeUsingPropertyBasedWithUnwrapped(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { final PropertyBasedCreator creator = _propertyBasedCreator; PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader); TokenBuffer tokens = new TokenBuffer(jp); tokens.writeStartObject(); JsonToken t = jp.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); jp.nextToken(); // to point to value // creator property? SettableBeanProperty creatorProp = creator.findCreatorProperty(propName); if (creatorProp != null) { // Last creator property to set? Object value = creatorProp.deserialize(jp, ctxt); if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) { t = jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt); continue; // never gets here } // if so, need to copy all remaining tokens into buffer while (t

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> == JsonToken.FIELD_NAME) { jp.nextToken(); // to skip name tokens.copyCurrentStructure(jp); t = jp.nextToken(); } tokens.writeEndObject(); if (bean.getClass() != _beanType.getRawClass()) { // !!! 08-Jul-2011, tatu: Could probably support; but for now // it's too complicated, so bail out throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values"); } return _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens); } continue; } // Object Id property? if (buffer.readIdProperty(propName)) { continue; } // regular property? needs buffering SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { buffer.bufferProperty(prop, prop.deserialize(jp, ctxt)); continue; } if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, handledType(), propName); continue; } tokens.writeFieldName(propName); tokens.copyCurrentStructure(jp); // "any property"? if (_anySetter != null) { buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt)); } } // We hit END_OBJECT, so: Object bean; // !!! 15-Feb-2012, tatu: Need to modify creator to use Builder! try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); return null; // never gets here } return _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens); } /* /********************************************************** /* Handling for cases where we have property/-ies with /* external type id /********************************************************** */ protected Object deserializeWithExternalTypeId(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (_propertyBasedCreator != null) { return deserializeUsingPropertyBasedWithExternalTypeId(jp, ctxt); } return deserializeWithExternalTypeId(jp

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>, ctxt, _valueInstantiator.createUsingDefault(ctxt)); } protected Object deserializeWithExternalTypeId(JsonParser jp, DeserializationContext ctxt, Object bean) throws IOException, JsonProcessingException { final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null; final ExternalTypeHandler ext = _externalTypeIdHandler.start(); for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) { String propName = jp.getCurrentName(); jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { // normal case if (activeView != null && !prop.visibleInView(activeView)) { jp.skipChildren(); continue; } try { bean = prop.deserializeSetAndReturn(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } // ignorable things should be ignored if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, bean, propName); continue; } // but others are likely to be part of external type id thingy... if (ext.handlePropertyValue(jp, ctxt, propName, bean)) { continue; } // if not, the usual fallback handling: if (_anySetter != null) { try { _anySetter.deserializeAndSet(jp, ctxt, bean, propName); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } else { // Unknown: let's call handler method handleUnknownProperty(jp, ctxt, bean, propName); } } // and when we get this far, let's try finalizing the deal: return ext.complete(jp, ctxt, bean); } protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // !!! 04-Mar-2012, TODO: Need to fix -- will not work as is... throw new IllegalStateException("Deserialization with Builder, External type id, @Json

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.impl; import java.io.IOException; import java.lang.reflect.Type; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import com.fasterxml.jackson.databind.ser.std.StdSerializer; public class UnknownSerializer extends StdSerializer<Object> { public UnknownSerializer() { super(Object.class); } @Override public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonMappingException { // 27-Nov-2009, tatu: As per [JACKSON-201] may or may not fail... if (provider.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)) { failForEmpty(value); } // But if it's fine, we'll just output empty JSON Object: jgen.writeStartObject(); jgen.writeEndObject(); } @Override public final void serializeWithType(Object value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonGenerationException { if (provider.isEnabled(SerializationFeature.FAIL_ON_EMPTY_BEANS)) { failForEmpty(value); } typeSer.writeTypePrefixForObject(value, jgen); typeSer.writeTypeSuffixForObject(value, jgen); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { return null; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { visitor.expectAnyFormat(typeHint); } protected void failForEmpty(Object value) throws JsonMappingException { throw new JsonMappingException("No serializer found for class "+value.getClass().getName()+" and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) )"); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>) { return new SetterlessProperty(this, newName); } @Override public SetterlessProperty withValueDeserializer(JsonDeserializer<?> deser) { return new SetterlessProperty(this, deser); } /* /********************************************************** /* BeanProperty impl /********************************************************** */ @Override public <A extends Annotation> A getAnnotation(Class<A> acls) { return _annotated.getAnnotation(acls); } @Override public AnnotatedMember getMember() { return _annotated; } /* /********************************************************** /* Overridden methods /********************************************************** */ @Override public final void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException, JsonProcessingException { JsonToken t = jp.getCurrentToken(); if (t == JsonToken.VALUE_NULL) { /* Hmmh. Is this a problem? We won't be setting anything, so it's * equivalent of empty Collection/Map in this case */ return; } // For [#501] fix we need to implement this but: if (_valueTypeDeserializer != null) { throw new JsonMappingException("Problem deserializing 'setterless' property: no way to handle typed deser with setterless yet"); // return _valueDeserializer.deserializeWithType(jp, ctxt, _valueTypeDeserializer); } // Ok: then, need to fetch Collection/Map to modify: Object toModify; try { toModify = _getter.invoke(instance); } catch (Exception e) { _throwAsIOE(e); return; // never gets here } /* Note: null won't work, since we can't then inject anything * in. At least that's not good in common case. However, * theoretically the case where we get JSON null might * be compatible. If so, implementation could be changed. */ if (toModify == null) { throw new JsonMappingException("Problem deserializing 'setterless' property '"+getName()+"': get method returned null"); } _valueDeserializer.deserialize(jp, ctxt, toModify); } @Override public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException, JsonProcessingException { deserializeAndSet(jp, ctxt, instance

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; import com.fasterxml.jackson.databind.type.*; /** * Interface that defines API for simple extensions that can provide additional deserializers * for various types. Access is by a single callback method; instance is to either return * a configured {@link JsonDeserializer} for specified type, or null to indicate that it * does not support handling of the type. In latter case, further calls can be made * for other providers; in former case returned deserializer is used for handling of * instances of specified type. *<p> * Unlike with {@link com.fasterxml.jackson.databind.ser.Serializers}, * multiple different methods are used since different kinds of types typically * require different kinds of inputs. */ public interface Deserializers { /** * Method called to locate serializer for specified array type. *<p> * Deserializer for element type may be passed, if configured explicitly at higher level (by * annotations, typically), but usually are not. * Type deserializer for element is passed if one is needed based on contextual information * (annotations on declared element class; or on field or method type is associated with). * * @param type Type of array instances to deserialize * @param config Configuration in effect * @param beanDesc Definition of the enumeration type that contains class annotations and * other information typically needed for building deserializers * @param elementTypeDeserializer If element type needs polymorphic type handling, this is * the type information deserializer to use; should usually be used as is when constructing * array deserializer. * @param elementDeserializer Deserializer to use for elements, if explicitly defined (by using * annotations, for exmple). May be null, in which case it should be resolved here (or using * {@link ResolvableDeserializer} callback) * * @return Deserializer to use for the type; or null if this provider does not know how to construct it */ public JsonDeserializer<?> findArrayDeserializer(ArrayType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException; /**

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> * Method called to locate serializer for specified {@link java.util.Collection} (List, Set etc) type. *<p> * Deserializer for element type may be passed, if configured explicitly at higher level (by * annotations, typically), but usually are not. * Type deserializer for element is passed if one is needed based on contextual information * (annotations on declared element class; or on field or method type is associated with). * * @param type Type of collection instances to deserialize * @param config Configuration in effect * @param beanDesc Definition of the enumeration type that contains class annotations and * other information typically needed for building deserializers * @param elementTypeDeserializer If element type needs polymorphic type handling, this is * the type information deserializer to use; should usually be used as is when constructing * array deserializer. * @param elementDeserializer Deserializer to use for elements, if explicitly defined (by using * annotations, for exmple). May be null, in which case it should be resolved here (or using * {@link ResolvableDeserializer} callback) * * @return Deserializer to use for the type; or null if this provider does not know how to construct it */ public JsonDeserializer<?> findCollectionDeserializer(CollectionType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException; /** * Method called to locate serializer for specified * "Collection-like" type (one that acts * like {@link java.util.Collection} but does not implement it). *<p> * Deserializer for element type may be passed, if configured explicitly at higher level (by * annotations, typically), but usually are not. * Type deserializer for element is passed if one is needed based on contextual information * (annotations on declared element class; or on field or method type is associated with). * * @param type Type of instances to deserialize * @param config Configuration in effect * @param beanDesc Definition of the enumeration type that contains class annotations and * other information typically needed for building deserializers * @param elementTypeDeserializer If element type needs polymorphic type handling, this is * the type information deserializer to use; should usually be used as is

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> when constructing * array deserializer. * @param elementDeserializer Deserializer to use for elements, if explicitly defined (by using * annotations, for exmple). May be null, in which case it should be resolved here (or using * {@link ResolvableDeserializer} callback) * * @return Deserializer to use for the type; or null if this provider does not know how to construct it */ public JsonDeserializer<?> findCollectionLikeDeserializer(CollectionLikeType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException; /** * Method called to locate deserializer for specified {@link java.lang.Enum} type. * * @param type Type of {@link java.lang.Enum} instances to deserialize * @param config Configuration in effect * @param beanDesc Definition of the enumeration type that contains class annotations and * other information typically needed for building deserializers * * @return Deserializer to use for the type; or null if this provider does not know how to construct it */ public JsonDeserializer<?> findEnumDeserializer(Class<?> type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException; /** * Method called to locate deserializer for specified {@link java.util.Map} type. *<p> * Deserializer for element type may be passed, if configured explicitly at higher level (by * annotations, typically), but usually are not. * Type deserializer for element is passed if one is needed based on contextual information * (annotations on declared element class; or on field or method type is associated with). *<p> * Similarly, a {@link KeyDeserializer} may be passed, but this is only done if there is * a specific configuration override (annotations) to indicate instance to use. * Otherwise null is passed, and key deserializer needs to be obtained later during * resolution (using {@link ResolvableDeserializer#resolve}). * * @param type Type of {@link java.util.Map} instances to deserialize * @param config Configuration in effect * @param beanDesc Definition of the enumeration type that contains class annotations and * other information typically needed for building deserializers * @param keyDeserializer Key deserializer use, if it is defined

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> via annotations or other configuration; * null if default key deserializer for key type can be used. * @param elementTypeDeserializer If element type needs polymorphic type handling, this is * the type information deserializer to use; should usually be used as is when constructing * array deserializer. * @param elementDeserializer Deserializer to use for elements, if explicitly defined (by using * annotations, for exmple). May be null, in which case it should be resolved here (or using * {@link ResolvableDeserializer} callback) * * @return Deserializer to use for the type; or null if this provider does not know how to construct it */ public JsonDeserializer<?> findMapDeserializer(MapType type, DeserializationConfig config, BeanDescription beanDesc, KeyDeserializer keyDeserializer, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException; /** * Method called to locate serializer for specified * "Map-like" type (one that acts * like {@link java.util.Map} but does not implement it). *<p> * Deserializer for element type may be passed, if configured explicitly at higher level (by * annotations, typically), but usually are not. * Type deserializer for element is passed if one is needed based on contextual information * (annotations on declared element class; or on field or method type is associated with). *<p> * Similarly, a {@link KeyDeserializer} may be passed, but this is only done if there is * a specific configuration override (annotations) to indicate instance to use. * Otherwise null is passed, and key deserializer needs to be obtained later during * resolution (using {@link ResolvableDeserializer#resolve}). * * @param type Type of {@link java.util.Map} instances to deserialize * @param config Configuration in effect * @param beanDesc Definition of the enumeration type that contains class annotations and * other information typically needed for building deserializers * @param keyDeserializer Key deserializer use, if it is defined via annotations or other configuration; * null if default key deserializer for key type can be used. * @param elementTypeDeserializer If element type needs polymorphic type handling, this is * the type information deserializer to use; should usually be used as

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> is when constructing * array deserializer. * @param elementDeserializer Deserializer to use for elements, if explicitly defined (by using * annotations, for exmple). May be null, in which case it should be resolved here (or using * {@link ResolvableDeserializer} callback) * * @return Deserializer to use for the type; or null if this provider does not know how to construct it */ public JsonDeserializer<?> findMapLikeDeserializer(MapLikeType type, DeserializationConfig config, BeanDescription beanDesc, KeyDeserializer keyDeserializer, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException; /** * Method called to locate deserializer for specified JSON tree node type. * * @param nodeType Specific type of JSON tree nodes to deserialize * (subtype of {@link com.fasterxml.jackson.databind.JsonNode}) * @param config Configuration in effect * * @return Deserializer to use for the type; or null if this provider does not know how to construct it */ public JsonDeserializer<?> findTreeNodeDeserializer(Class<? extends JsonNode> nodeType, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException; /** * Method called to locate deserializer for specified value type which does not belong to any other * category (not an Enum, Collection, Map, Array or tree node) * * @param type Bean type to deserialize * @param config Configuration in effect * @param beanDesc Definition of the enumeration type that contains class annotations and * other information typically needed for building deserializers * * @return Deserializer to use for the type; or null if this provider does not know how to construct it */ public JsonDeserializer<?> findBeanDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException; /* /********************************************************** /* Helper classes /********************************************************** */ /** * Basic {@link Deserializers} implementation that implements all methods but provides * no deserializers. Its main purpose is to serve as a base class so that * sub-classes only need to override methods they need, as most of the time some * of methods are not needed (especially enumeration and array deserializers are * very rarely overridden). */ public static class Base implements Deserial

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>izers { @Override public JsonDeserializer<?> findArrayDeserializer(ArrayType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { return null; } @Override public JsonDeserializer<?> findCollectionDeserializer(CollectionType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { return null; } @Override public JsonDeserializer<?> findCollectionLikeDeserializer(CollectionLikeType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { return null; } @Override public JsonDeserializer<?> findMapDeserializer(MapType type, DeserializationConfig config, BeanDescription beanDesc, KeyDeserializer keyDeserializer, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { return null; } @Override public JsonDeserializer<?> findMapLikeDeserializer(MapLikeType type, DeserializationConfig config, BeanDescription beanDesc, KeyDeserializer keyDeserializer, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { return null; } @Override public JsonDeserializer<?> findEnumDeserializer(Class<?> type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { return null; } @Override public JsonDeserializer<?> findTreeNodeDeserializer(Class<? extends JsonNode> nodeType, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { return null; } @Override public JsonDeserializer<?> findBeanDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { return null; } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser; import com.fasterxml.jackson.databind.*; /** * Interface used to indicate serializers that want to do post-processing * after construction and being added to {@link SerializerProvider}, * but before being used. This is typically used to resolve references * to other contained types; for example, bean serializers use this * to eagerly find serializers for contained field types. *<p> * Note that in cases where serializer needs both contextualization and * resolution -- that is, implements both this interface and {@link ContextualSerializer} * -- resolution via this interface occurs first, and contextual * resolution (using {@link ContextualSerializer}) later on. */ public interface ResolvableSerializer { /** * Method called after {@link SerializerProvider} has registered * the serializer, but before it has returned it to the caller. * Called object can then resolve its dependencies to other types, * including self-references (direct or indirect). *<p> * Note that this method does NOT return serializer, since resolution * is not allowed to change actual serializer to use. * * @param provider Provider that has constructed serializer this method * is called on. */ public abstract void resolve(SerializerProvider provider) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>> A getAnnotation(Class<A> acls) { return _delegate.getAnnotation(acls); } @Override public AnnotatedMember getMember() { return _delegate.getMember(); } /* /********************************************************** /* Deserialization methods /********************************************************** */ @Override public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object bean) throws IOException, JsonProcessingException { JsonToken t = jp.getCurrentToken(); Object value; if (t == JsonToken.VALUE_NULL) { value = (_nullProvider == null) ? null : _nullProvider.nullValue(ctxt); } else if (_valueTypeDeserializer != null) { value = _valueDeserializer.deserializeWithType(jp, ctxt, _valueTypeDeserializer); } else { // the usual case try { value = _creator.newInstance(bean); } catch (Exception e) { ClassUtil.unwrapAndThrowAsIAE(e, "Failed to instantiate class "+_creator.getDeclaringClass().getName()+", problem: "+e.getMessage()); value = null; } _valueDeserializer.deserialize(jp, ctxt, value); } set(bean, value); } @Override public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException, JsonProcessingException { return setAndReturn(instance, deserialize(jp, ctxt)); } @Override public final void set(Object instance, Object value) throws IOException { _delegate.set(instance, value); } @Override public Object setAndReturn(Object instance, Object value) throws IOException { return _delegate.setAndReturn(instance, value); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> shareable thread-safe instance which has no additional custom deserializers * registered */ public final static BeanDeserializerFactory instance = new BeanDeserializerFactory( new DeserializerFactoryConfig()); public BeanDeserializerFactory(DeserializerFactoryConfig config) { super(config); } /** * Method used by module registration functionality, to construct a new bean * deserializer factory * with different configuration settings. */ @Override public DeserializerFactory withConfig(DeserializerFactoryConfig config) { if (_factoryConfig == config) { return this; } /* 22-Nov-2010, tatu: Handling of subtypes is tricky if we do immutable-with-copy-ctor; * and we pretty much have to here either choose between losing subtype instance * when registering additional deserializers, or losing deserializers. * Instead, let's actually just throw an error if this method is called when subtype * has not properly overridden this method; this to indicate problem as soon as possible. */ if (getClass() != BeanDeserializerFactory.class) { throw new IllegalStateException("Subtype of BeanDeserializerFactory ("+getClass().getName() +") has not properly overridden method 'withAdditionalDeserializers': can not instantiate subtype with " +"additional deserializer definitions"); } return new BeanDeserializerFactory(config); } /* /********************************************************** /* Overrides for super-class methods used for finding /* custom deserializers /********************************************************** */ // Note: NOT overriding, superclass has no matching method @SuppressWarnings("unchecked") protected JsonDeserializer<Object> _findCustomBeanDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { for (Deserializers d : _factoryConfig.deserializers()) { JsonDeserializer<?> deser = d.findBeanDeserializer(type, config, beanDesc); if (deser != null) { return (JsonDeserializer<Object>) deser; } } return null; } /* /********************************************************** /* DeserializerFactory API implementation /********************************************************** */ /** * Method that {@link DeserializerCache}s call to create a new * deserializer for types other than Collections, Maps, arrays and * enums. */ @Override public JsonDeserializer<Object> createBean

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Deserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); // We may also have custom overrides: JsonDeserializer<Object> custom = _findCustomBeanDeserializer(type, config, beanDesc); if (custom != null) { return custom; } /* One more thing to check: do we have an exception type * (Throwable or its sub-classes)? If so, need slightly * different handling. */ if (type.isThrowable()) { return buildThrowableDeserializer(ctxt, type, beanDesc); } /* Or, for abstract types, may have alternate means for resolution * (defaulting, materialization) */ if (type.isAbstract()) { // [JACKSON-41] (v1.6): Let's make it possible to materialize abstract types. JavaType concreteType = materializeAbstractType(ctxt, type, beanDesc); if (concreteType != null) { /* important: introspect actual implementation (abstract class or * interface doesn't have constructors, for one) */ beanDesc = config.introspect(concreteType); return buildBeanDeserializer(ctxt, concreteType, beanDesc); } } // Otherwise, may want to check handlers for standard types, from superclass: @SuppressWarnings("unchecked") JsonDeserializer<Object> deser = (JsonDeserializer<Object>) findStdDeserializer(ctxt, type, beanDesc); if (deser != null) { return deser; } // Otherwise: could the class be a Bean class? If not, bail out if (!isPotentialBeanType(type.getRawClass())) { return null; } // Use generic bean introspection to build deserializer return buildBeanDeserializer(ctxt, type, beanDesc); } @Override public JsonDeserializer<Object> createBuilderBasedDeserializer( DeserializationContext ctxt, JavaType valueType, BeanDescription beanDesc, Class<?> builderClass) throws JsonMappingException { // First: need a BeanDescription for builder class JavaType builderType = ctxt.constructType(builderClass); BeanDescription builderDesc = ctxt.getConfig().introspectForBuilder(builderType); return buildBuilderBasedDeserializer(ctxt, valueType

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>, builderDesc); } /** * Method called by {@link BeanDeserializerFactory} to see if there might be a standard * deserializer registered for given type. */ protected JsonDeserializer<?> findStdDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { // note: we do NOT check for custom deserializers here, caller has already // done that JsonDeserializer<?> deser = findDefaultDeserializer(ctxt, type, beanDesc); if (deser != null) { return deser; } Class<?> cls = type.getRawClass(); // [JACKSON-283]: AtomicReference is a rather special type... if (AtomicReference.class.isAssignableFrom(cls)) { // Must find parameterization TypeFactory tf = ctxt.getTypeFactory(); JavaType[] params = tf.findTypeParameters(type, AtomicReference.class); JavaType referencedType; if (params == null || params.length < 1) { // untyped (raw) referencedType = TypeFactory.unknownType(); } else { referencedType = params[0]; } TypeDeserializer valueTypeDeser = findTypeDeserializer(ctxt.getConfig(), referencedType); BeanDescription refdDesc = ctxt.getConfig().introspectClassAnnotations(referencedType); deser = findDeserializerFromAnnotation(ctxt, refdDesc.getClassInfo()); return new AtomicReferenceDeserializer(referencedType, valueTypeDeser, deser); } return findOptionalStdDeserializer(ctxt, type, beanDesc); } /** * Overridable method called after checking all other types. * * @since 2.2 */ protected JsonDeserializer<?> findOptionalStdDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { return OptionalHandlerFactory.instance.findDeserializer(type, ctxt.getConfig(), beanDesc); } protected JavaType materializeAbstractType(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { final JavaType abstractType = beanDesc.getType(); // [JACKSON-502]: Now it is possible to have multiple resolvers too, // as they are registered via module interface. for (AbstractTypeResolver r : _factoryConfig.abstractTypeResolvers

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>()) { JavaType concrete = r.resolveAbstractType(ctxt.getConfig(), abstractType); if (concrete != null) { return concrete; } } return null; } /* /********************************************************** /* Public construction method beyond DeserializerFactory API: /* can be called from outside as well as overridden by /* sub-classes /********************************************************** */ /** * Method that is to actually build a bean deserializer instance. * All basic sanity checks have been done to know that what we have * may be a valid bean type, and that there are no default simple * deserializers. */ @SuppressWarnings("unchecked") public JsonDeserializer<Object> buildBeanDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { // First: check what creators we can use, if any ValueInstantiator valueInstantiator = findValueInstantiator(ctxt, beanDesc); BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(ctxt, beanDesc); builder.setValueInstantiator(valueInstantiator); // And then setters for deserializing from JSON Object addBeanProps(ctxt, beanDesc, builder); addObjectIdReader(ctxt, beanDesc, builder); // managed/back reference fields/setters need special handling... first part addReferenceProperties(ctxt, beanDesc, builder); addInjectables(ctxt, beanDesc, builder); final DeserializationConfig config = ctxt.getConfig(); // [JACKSON-440]: update builder now that all information is in? if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { builder = mod.updateBuilder(config, beanDesc, builder); } } JsonDeserializer<?> deserializer; /* 19-Mar-2012, tatu: This check used to be done earlier; but we have to defer * it a bit to collect information on ObjectIdReader, for example. */ if (type.isAbstract() && !valueInstantiator.canInstantiate()) { deserializer = builder.buildAbstract(); } else { deserializer = builder.build(); } // [JACKSON-440]: may have modifier(s) that wants to modify or replace serializer we just

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> built: if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deserializer = mod.modifyDeserializer(config, beanDesc, deserializer); } } return (JsonDeserializer<Object>) deserializer; } /** * Method for constructing a bean deserializer that uses specified * intermediate Builder for binding data, and construction of the * value instance. * Note that implementation is mostly copied from the regular * BeanDeserializer build method. */ @SuppressWarnings("unchecked") protected JsonDeserializer<Object> buildBuilderBasedDeserializer( DeserializationContext ctxt, JavaType valueType, BeanDescription builderDesc) throws JsonMappingException { // Creators, anyone? (to create builder itself) ValueInstantiator valueInstantiator = findValueInstantiator(ctxt, builderDesc); final DeserializationConfig config = ctxt.getConfig(); BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(ctxt, builderDesc); builder.setValueInstantiator(valueInstantiator); // And then "with methods" for deserializing from JSON Object addBeanProps(ctxt, builderDesc, builder); addObjectIdReader(ctxt, builderDesc, builder); // managed/back reference fields/setters need special handling... first part addReferenceProperties(ctxt, builderDesc, builder); addInjectables(ctxt, builderDesc, builder); JsonPOJOBuilder.Value builderConfig = builderDesc.findPOJOBuilderConfig(); final String buildMethodName = (builderConfig == null) ? "build" : builderConfig.buildMethodName; // and lastly, find build method to use: AnnotatedMethod buildMethod = builderDesc.findMethod(buildMethodName, null); if (buildMethod != null) { // note: can't yet throw error; may be given build method if (config.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(buildMethod.getMember()); } } builder.setPOJOBuilder(buildMethod, builderConfig); // this may give us more information... if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { builder = mod.updateBuilder(config, builderDesc, builder); } } JsonDeserializer<?> deserializer = builder

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>.buildBuilderBased( valueType, buildMethodName); // [JACKSON-440]: may have modifier(s) that wants to modify or replace serializer we just built: if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deserializer = mod.modifyDeserializer(config, builderDesc, deserializer); } } return (JsonDeserializer<Object>) deserializer; } protected void addObjectIdReader(DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder) throws JsonMappingException { ObjectIdInfo objectIdInfo = beanDesc.getObjectIdInfo(); if (objectIdInfo == null) { return; } Class<?> implClass = objectIdInfo.getGeneratorType(); JavaType idType; SettableBeanProperty idProp; ObjectIdGenerator<?> gen; ObjectIdResolver resolver = ctxt.objectIdResolverInstance(beanDesc.getClassInfo(), objectIdInfo); // Just one special case: Property-based generator is trickier if (implClass == ObjectIdGenerators.PropertyGenerator.class) { // most special one, needs extra work PropertyName propName = objectIdInfo.getPropertyName(); idProp = builder.findProperty(propName); if (idProp == null) { throw new IllegalArgumentException("Invalid Object Id definition for " +beanDesc.getBeanClass().getName()+": can not find property with name '"+propName+"'"); } idType = idProp.getType(); gen = new PropertyBasedObjectIdGenerator(objectIdInfo.getScope()); } else { JavaType type = ctxt.constructType(implClass); idType = ctxt.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0]; idProp = null; gen = ctxt.objectIdGeneratorInstance(beanDesc.getClassInfo(), objectIdInfo); } // also: unlike with value deserializers, let's just resolve one we need here JsonDeserializer<?> deser = ctxt.findRootValueDeserializer(idType); builder.setObjectIdReader(ObjectIdReader.construct(idType, objectIdInfo.getPropertyName(), gen, deser, idProp, resolver)); } @SuppressWarnings("unchecked") public JsonDeserializer<Object> buildThrowableDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription bean

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Desc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); // first: construct like a regular bean deserializer... BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(ctxt, beanDesc); builder.setValueInstantiator(findValueInstantiator(ctxt, beanDesc)); addBeanProps(ctxt, beanDesc, builder); // (and assume there won't be any back references) // But then let's decorate things a bit /* To resolve [JACKSON-95], need to add "initCause" as setter * for exceptions (sub-classes of Throwable). */ AnnotatedMethod am = beanDesc.findMethod("initCause", INIT_CAUSE_PARAMS); if (am != null) { // should never be null SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct(ctxt.getConfig(), am, "cause"); SettableBeanProperty prop = constructSettableProperty(ctxt, beanDesc, propDef, am.getGenericParameterType(0)); if (prop != null) { /* 21-Aug-2011, tatus: We may actually have found 'cause' property * to set (with new 1.9 code)... but let's replace it just in case, * otherwise can end up with odd errors. */ builder.addOrReplaceProperty(prop, true); } } // And also need to ignore "localizedMessage" builder.addIgnorable("localizedMessage"); // [JACKSON-794]: JDK 7 also added "getSuppressed", skip if we have such data: builder.addIgnorable("suppressed"); /* As well as "message": it will be passed via constructor, * as there's no 'setMessage()' method */ builder.addIgnorable("message"); // [JACKSON-440]: update builder now that all information is in? if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { builder = mod.updateBuilder(config, beanDesc, builder); } } JsonDeserializer<?> deserializer = builder.build(); /* At this point it ought to be a BeanDeserializer; if not, must assume * it's some other thing that can

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> handle deserialization ok... */ if (deserializer instanceof BeanDeserializer) { deserializer = new ThrowableDeserializer((BeanDeserializer) deserializer); } // [JACKSON-440]: may have modifier(s) that wants to modify or replace serializer we just built: if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deserializer = mod.modifyDeserializer(config, beanDesc, deserializer); } } return (JsonDeserializer<Object>) deserializer; } /* /********************************************************** /* Helper methods for Bean deserializer construction, /* overridable by sub-classes /********************************************************** */ /** * Overridable method that constructs a {@link BeanDeserializerBuilder} * which is used to accumulate information needed to create deserializer * instance. */ protected BeanDeserializerBuilder constructBeanDeserializerBuilder(DeserializationContext ctxt, BeanDescription beanDesc) { return new BeanDeserializerBuilder(beanDesc, ctxt.getConfig()); } /** * Method called to figure out settable properties for the * bean deserializer to use. *<p> * Note: designed to be overridable, and effort is made to keep interface * similar between versions. */ protected void addBeanProps(DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder) throws JsonMappingException { final SettableBeanProperty[] creatorProps = builder.getValueInstantiator().getFromObjectArguments(ctxt.getConfig()); // Things specified as "ok to ignore"? [JACKSON-77] AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); boolean ignoreAny = false; { Boolean B = intr.findIgnoreUnknownProperties(beanDesc.getClassInfo()); if (B != null) { ignoreAny = B.booleanValue(); builder.setIgnoreUnknownProperties(ignoreAny); } } // Or explicit/implicit definitions? Set<String> ignored = ArrayBuilders.arrayToSet(intr.findPropertiesToIgnore(beanDesc.getClassInfo())); for (String propName : ignored) { builder.addIgnorable(propName); } // Also, do we have a fallback "any" setter? AnnotatedMethod anySetter = beanDesc.findAny

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>orable types". * Note that this will not remove properties that have no * setters. */ protected List<BeanPropertyDefinition> filterBeanProps(DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder, List<BeanPropertyDefinition> propDefsIn, Set<String> ignored) throws JsonMappingException { ArrayList<BeanPropertyDefinition> result = new ArrayList<BeanPropertyDefinition>( Math.max(4, propDefsIn.size())); HashMap<Class<?>,Boolean> ignoredTypes = new HashMap<Class<?>,Boolean>(); // These are all valid setters, but we do need to introspect bit more for (BeanPropertyDefinition property : propDefsIn) { String name = property.getName(); if (ignored.contains(name)) { // explicit ignoral using @JsonIgnoreProperties needs to block entries continue; } if (!property.hasConstructorParameter()) { // never skip constructor params Class<?> rawPropertyType = null; if (property.hasSetter()) { rawPropertyType = property.getSetter().getRawParameterType(0); } else if (property.hasField()) { rawPropertyType = property.getField().getRawType(); } // [JACKSON-429] Some types are declared as ignorable as well if ((rawPropertyType != null) && (isIgnorableType(ctxt.getConfig(), beanDesc, rawPropertyType, ignoredTypes))) { // important: make ignorable, to avoid errors if value is actually seen builder.addIgnorable(name); continue; } } result.add(property); } return result; } /** * Method that will find if bean has any managed- or back-reference properties, * and if so add them to bean, to be linked during resolution phase. */ protected void addReferenceProperties(DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder) throws JsonMappingException { // and then back references, not necessarily found as regular properties Map<String,AnnotatedMember> refs = beanDesc.findBackReferenceProperties(); if (refs != null) { for (Map.Entry<String, AnnotatedMember> en : refs.entrySet()) { String name = en.getKey(); AnnotatedMember m = en.getValue(); Type genericType; if (m

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> instanceof AnnotatedMethod) { genericType = ((AnnotatedMethod) m).getGenericParameterType(0); } else { genericType = m.getRawType(); } SimpleBeanPropertyDefinition propDef = SimpleBeanPropertyDefinition.construct( ctxt.getConfig(), m); builder.addBackReferenceProperty(name, constructSettableProperty( ctxt, beanDesc, propDef, genericType)); } } } /** * Method called locate all members used for value injection (if any), * constructor {@link com.fasterxml.jackson.databind.deser.impl.ValueInjector} instances, and add them to builder. */ protected void addInjectables(DeserializationContext ctxt, BeanDescription beanDesc, BeanDeserializerBuilder builder) throws JsonMappingException { Map<Object, AnnotatedMember> raw = beanDesc.findInjectables(); if (raw != null) { boolean fixAccess = ctxt.canOverrideAccessModifiers(); for (Map.Entry<Object, AnnotatedMember> entry : raw.entrySet()) { AnnotatedMember m = entry.getValue(); if (fixAccess) { m.fixAccess(); // to ensure we can call it } builder.addInjectable(new PropertyName(m.getName()), beanDesc.resolveType(m.getGenericType()), beanDesc.getClassAnnotations(), m, entry.getKey()); } } } /** * Method called to construct fallback {@link SettableAnyProperty} * for handling unknown bean properties, given a method that * has been designated as such setter. */ protected SettableAnyProperty constructAnySetter(DeserializationContext ctxt, BeanDescription beanDesc, AnnotatedMethod setter) throws JsonMappingException { if (ctxt.canOverrideAccessModifiers()) { setter.fixAccess(); // to ensure we can call it } // we know it's a 2-arg method, second arg is the value JavaType type = beanDesc.bindingsForBeanType().resolveType(setter.getGenericParameterType(1)); BeanProperty.Std property = new BeanProperty.Std(new PropertyName(setter.getName()), type, null, beanDesc.getClassAnnotations(), setter, PropertyMetadata.STD_OPTIONAL); type = resolveType(ctxt, beanDesc, type, setter); /* AnySetter can be

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> annotated with @JsonClass (etc) just like a * regular setter... so let's see if those are used. * Returns null if no annotations, in which case binding will * be done at a later point. */ JsonDeserializer<Object> deser = findDeserializerFromAnnotation(ctxt, setter); /* Otherwise, method may specify more specific (sub-)class for * value (no need to check if explicit deser was specified): */ type = modifyTypeByAnnotation(ctxt, setter, type); if (deser == null) { deser = type.getValueHandler(); } TypeDeserializer typeDeser = type.getTypeHandler(); return new SettableAnyProperty(property, setter, type, deser, typeDeser); } /** * Method that will construct a regular bean property setter using * the given setter method. * * @return Property constructed, if any; or null to indicate that * there should be no property based on given definitions. */ protected SettableBeanProperty constructSettableProperty(DeserializationContext ctxt, BeanDescription beanDesc, BeanPropertyDefinition propDef, Type jdkType) throws JsonMappingException { // need to ensure method is callable (for non-public) AnnotatedMember mutator = propDef.getNonConstructorMutator(); if (ctxt.canOverrideAccessModifiers()) { mutator.fixAccess(); } // note: this works since we know there's exactly one argument for methods JavaType t0 = beanDesc.resolveType(jdkType); BeanProperty.Std property = new BeanProperty.Std(propDef.getFullName(), t0, propDef.getWrapperName(), beanDesc.getClassAnnotations(), mutator, propDef.getMetadata()); JavaType type = resolveType(ctxt, beanDesc, t0, mutator); // did type change? if (type != t0) { property = property.withType(type); } /* First: does the Method specify the deserializer to use? * If so, let's use it. */ JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(ctxt, mutator); type = modifyTypeByAnnotation(ctxt, mutator, type); TypeDeserializer typeDeser = type.getTypeHandler(); SettableBeanProperty prop;

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> if (mutator instanceof AnnotatedMethod) { prop = new MethodProperty(propDef, type, typeDeser, beanDesc.getClassAnnotations(), (AnnotatedMethod) mutator); } else { prop = new FieldProperty(propDef, type, typeDeser, beanDesc.getClassAnnotations(), (AnnotatedField) mutator); } if (propDeser != null) { prop = prop.withValueDeserializer(propDeser); } // [JACKSON-235]: need to retain name of managed forward references: AnnotationIntrospector.ReferenceProperty ref = propDef.findReferenceType(); if (ref != null && ref.isManagedReference()) { prop.setManagedReferenceName(ref.getName()); } ObjectIdInfo objectIdInfo = propDef.findObjectIdInfo(); if(objectIdInfo != null){ prop.setObjectIdInfo(objectIdInfo); } return prop; } /** * Method that will construct a regular bean property setter using * the given setter method. */ protected SettableBeanProperty constructSetterlessProperty(DeserializationContext ctxt, BeanDescription beanDesc, BeanPropertyDefinition propDef) throws JsonMappingException { final AnnotatedMethod getter = propDef.getGetter(); // need to ensure it is callable now: if (ctxt.canOverrideAccessModifiers()) { getter.fixAccess(); } /* 26-Jan-2012, tatu: Alas, this complication is still needed to handle * (or at least work around) local type declarations... */ JavaType type = getter.getType(beanDesc.bindingsForBeanType()); /* First: does the Method specify the deserializer to use? * If so, let's use it. */ JsonDeserializer<Object> propDeser = findDeserializerFromAnnotation(ctxt, getter); type = modifyTypeByAnnotation(ctxt, getter, type); // As per [Issue#501], need full resolution: type = resolveType(ctxt, beanDesc, type, getter); TypeDeserializer typeDeser = type.getTypeHandler(); SettableBeanProperty prop = new SetterlessProperty(propDef, type, typeDeser, beanDesc.getClassAnnotations(), getter); if (propDeser != null) { prop

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser; import com.fasterxml.jackson.databind.*; /** * Add-on interface that {@link JsonSerializer}s can implement to get a callback * that can be used to create contextual instances of serializer to use for * handling properties of supported type. This can be useful * for serializers that can be configured by annotations, or should otherwise * have differing behavior depending on what kind of property is being serialized. *<p> * Note that in cases where serializer needs both contextualization and * resolution -- that is, implements both this interface and {@link ResolvableSerializer} * -- resolution via {@link ResolvableSerializer} occurs first, and contextual * resolution (via this interface) later on. */ public interface ContextualSerializer { /** * Method called to see if a different (or differently configured) serializer * is needed to serialize values of specified property. * Note that instance that this method is called on is typically shared one and * as a result method should <b>NOT</b> modify this instance but rather construct * and return a new instance. This instance should only be returned as-is, in case * it is already suitable for use. * * @param prov Serializer provider to use for accessing config, other serializers * @param property Method or field that represents the property * (and is used to access value to serialize). * Should be available; but there may be cases where caller can not provide it and * null is passed instead (in which case impls usually pass 'this' serializer as is) * * @return Serializer to use for serializing values of specified property; * may be this instance or a new instance. * * @throws JsonMappingException */ public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.IOException; import java.lang.reflect.Type; import java.util.concurrent.atomic.AtomicReference; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonSerializable; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.jsonschema.JsonSerializableSchema; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.type.TypeFactory; /** * Generic handler for types that implement {@link JsonSerializable}. *<p> * Note: given that this is used for anything that implements * interface, can not be checked for direct class equivalence. */ @JacksonStdImpl public class SerializableSerializer extends StdSerializer<JsonSerializable> { public final static SerializableSerializer instance = new SerializableSerializer(); // Ugh. Should NOT need this... private final static AtomicReference<ObjectMapper> _mapperReference = new AtomicReference<ObjectMapper>(); protected SerializableSerializer() { super(JsonSerializable.class); } @Override public void serialize(JsonSerializable value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { value.serialize(jgen, provider); } @Override public final void serializeWithType(JsonSerializable value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonGenerationException { value.serializeWithType(jgen, provider, typeSer); } @Override @SuppressWarnings("deprecation") public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { ObjectNode objectNode = createObjectNode(); String schemaType = "any"; String objectProperties = null;

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> String itemDefinition = null; if (typeHint != null) { Class<?> rawClass = TypeFactory.rawClass(typeHint); if (rawClass.isAnnotationPresent(JsonSerializableSchema.class)) { JsonSerializableSchema schemaInfo = rawClass.getAnnotation(JsonSerializableSchema.class); schemaType = schemaInfo.schemaType(); if (!JsonSerializableSchema.NO_VALUE.equals(schemaInfo.schemaObjectPropertiesDefinition())) { objectProperties = schemaInfo.schemaObjectPropertiesDefinition(); } if (!JsonSerializableSchema.NO_VALUE.equals(schemaInfo.schemaItemDefinition())) { itemDefinition = schemaInfo.schemaItemDefinition(); } } } /* 19-Mar-2012, tatu: geez, this is butt-ugly abonimation of code... * really, really should not require back ref to an ObjectMapper. */ objectNode.put("type", schemaType); if (objectProperties != null) { try { objectNode.put("properties", _getObjectMapper().readTree(objectProperties)); } catch (IOException e) { throw new JsonMappingException("Failed to parse @JsonSerializableSchema.schemaObjectPropertiesDefinition value"); } } if (itemDefinition != null) { try { objectNode.put("items", _getObjectMapper().readTree(itemDefinition)); } catch (IOException e) { throw new JsonMappingException("Failed to parse @JsonSerializableSchema.schemaItemDefinition value"); } } // always optional, no need to specify: //objectNode.put("required", false); return objectNode; } private final static synchronized ObjectMapper _getObjectMapper() { ObjectMapper mapper = _mapperReference.get(); if (mapper == null) { mapper = new ObjectMapper(); _mapperReference.set(mapper); } return mapper; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { visitor.expectAnyFormat(typeHint); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>-blueprint instances from the blueprint. * This is needed to retain state during serialization. */ public abstract DefaultSerializerProvider createInstance(SerializationConfig config, SerializerFactory jsf); /** * The method to be called by {@link ObjectMapper} and {@link ObjectWriter} * for serializing given value, using serializers that * this provider has access to (via caching and/or creating new serializers * as need be). */ public void serializeValue(JsonGenerator jgen, Object value) throws IOException { if (value == null) { _serializeNull(jgen); return; } Class<?> cls = value.getClass(); // true, since we do want to cache root-level typed serializers (ditto for null property) final JsonSerializer<Object> ser = findTypedValueSerializer(cls, true, null); // Ok: should we wrap result in an additional property ("root name")? final boolean wrap; String rootName = _config.getRootName(); if (rootName == null) { // not explicitly specified // [JACKSON-163] wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE); if (wrap) { PropertyName pname = _rootNames.findRootName(value.getClass(), _config); jgen.writeStartObject(); jgen.writeFieldName(pname.simpleAsEncoded(_config)); } } else if (rootName.length() == 0) { wrap = false; } else { // [JACKSON-764] // empty String means explicitly disabled; non-empty that it is enabled wrap = true; jgen.writeStartObject(); jgen.writeFieldName(rootName); } try { ser.serialize(value, jgen, this); if (wrap) { jgen.writeEndObject(); } } catch (IOException ioe) { // As per [JACKSON-99], pass IOException and subtypes as-is throw ioe; } catch (Exception e) { // but wrap RuntimeExceptions, to get path information String msg = e.getMessage(); if (msg == null) { msg = "[no message for "+e.getClass().getName()+"]"; } throw new JsonMappingException(msg, e);

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } } /** * The method to be called by {@link ObjectMapper} and {@link ObjectWriter} * for serializing given value (assumed to be of specified root type, * instead of runtime type of value), * using serializers that * this provider has access to (via caching and/or creating new serializers * as need be), * * @param rootType Type to use for locating serializer to use, instead of actual * runtime type. Must be actual type, or one of its super types */ public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType) throws IOException { if (value == null) { _serializeNull(jgen); return; } // Let's ensure types are compatible at this point if (!rootType.getRawClass().isAssignableFrom(value.getClass())) { _reportIncompatibleRootType(value, rootType); } // root value, not reached via property: JsonSerializer<Object> ser = findTypedValueSerializer(rootType, true, null); // Ok: should we wrap result in an additional property ("root name")? final boolean wrap; String rootName = _config.getRootName(); if (rootName == null) { // not explicitly specified // [JACKSON-163] wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE); if (wrap) { jgen.writeStartObject(); PropertyName pname = _rootNames.findRootName(value.getClass(), _config); jgen.writeFieldName(pname.simpleAsEncoded(_config)); } } else if (rootName.length() == 0) { wrap = false; } else { // [JACKSON-764] // empty String means explicitly disabled; non-empty that it is enabled wrap = true; jgen.writeStartObject(); jgen.writeFieldName(rootName); } try { ser.serialize(value, jgen, this); if (wrap) { jgen.writeEndObject(); } } catch (IOException ioe) { // no wrapping for IO (and derived) throw ioe; } catch (Exception e) { // but others do need to be, to get path etc String msg =

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> e.getMessage(); if (msg == null) { msg = "[no message for "+e.getClass().getName()+"]"; } throw new JsonMappingException(msg, e); } } /** * The method to be called by {@link ObjectWriter} * for serializing given value (assumed to be of specified root type, * instead of runtime type of value), when it may know specific * {@link JsonSerializer} to use. * * @param rootType Type to use for locating serializer to use, instead of actual * runtime type, if no serializer is passed * @param ser Root Serializer to use, if not null * * @since 2.1 */ public void serializeValue(JsonGenerator jgen, Object value, JavaType rootType, JsonSerializer<Object> ser) throws IOException { if (value == null) { _serializeNull(jgen); return; } // Let's ensure types are compatible at this point if ((rootType != null) && !rootType.getRawClass().isAssignableFrom(value.getClass())) { _reportIncompatibleRootType(value, rootType); } // root value, not reached via property: if (ser == null) { ser = findTypedValueSerializer(rootType, true, null); } // Ok: should we wrap result in an additional property ("root name")? final boolean wrap; String rootName = _config.getRootName(); if (rootName == null) { // not explicitly specified // [JACKSON-163] wrap = _config.isEnabled(SerializationFeature.WRAP_ROOT_VALUE); if (wrap) { jgen.writeStartObject(); PropertyName pname = (rootType == null) ? _rootNames.findRootName(value.getClass(), _config) : _rootNames.findRootName(rootType, _config); jgen.writeFieldName(pname.simpleAsEncoded(_config)); } } else if (rootName.length() == 0) { wrap = false; } else { // [JACKSON-764] // empty String means explicitly disabled; non-empty that it is enabled wrap = true; jgen.writeStartObject(); jgen.writeFieldName(

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>rootName); } try { ser.serialize(value, jgen, this); if (wrap) { jgen.writeEndObject(); } } catch (IOException ioe) { // no wrapping for IO (and derived) throw ioe; } catch (Exception e) { // but others do need to be, to get path etc String msg = e.getMessage(); if (msg == null) { msg = "[no message for "+e.getClass().getName()+"]"; } throw new JsonMappingException(msg, e); } } /** * Helper method called when root value to serialize is null * * @since 2.3 */ protected void _serializeNull(JsonGenerator jgen) throws IOException { JsonSerializer<Object> ser = getDefaultNullValueSerializer(); try { ser.serialize(null, jgen, this); } catch (IOException ioe) { // no wrapping for IO (and derived) throw ioe; } catch (Exception e) { // but others do need to be, to get path etc String msg = e.getMessage(); if (msg == null) { msg = "[no message for "+e.getClass().getName()+"]"; } throw new JsonMappingException(msg, e); } } /** * The method to be called by {@link ObjectMapper} and {@link ObjectWriter} * to generate <a href="http://json-schema.org/">JSON schema</a> for * given type. * * @param type The type for which to generate schema */ @SuppressWarnings("deprecation") public com.fasterxml.jackson.databind.jsonschema.JsonSchema generateJsonSchema(Class<?> type) throws JsonMappingException { if (type == null) { throw new IllegalArgumentException("A class must be provided"); } /* no need for embedded type information for JSON schema generation (all * type information it needs is accessible via "untyped" serializer) */ JsonSerializer<Object> ser = findValueSerializer(type, null); JsonNode schemaNode = (ser instanceof SchemaAware) ? ((SchemaAware) ser).getSchema(this, null) : com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode(); if (!(schemaNode instanceof ObjectNode)) {

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> throw new IllegalArgumentException("Class " + type.getName() +" would not be serialized as a JSON object and therefore has no schema"); } return new com.fasterxml.jackson.databind.jsonschema.JsonSchema((ObjectNode) schemaNode); } /** * The method to be called by {@link ObjectMapper} and {@link ObjectWriter} * to to expose the format of the given to to the given visitor * * @param javaType The type for which to generate format * @param visitor the visitor to accept the format */ public void acceptJsonFormatVisitor(JavaType javaType, JsonFormatVisitorWrapper visitor) throws JsonMappingException { if (javaType == null) { throw new IllegalArgumentException("A class must be provided"); } /* no need for embedded type information for JSON schema generation (all * type information it needs is accessible via "untyped" serializer) */ visitor.setProvider(this); findValueSerializer(javaType, null).acceptJsonFormatVisitor(visitor, javaType); } @Deprecated // since 2.3; use the overloaded variant public boolean hasSerializerFor(Class<?> cls) { return hasSerializerFor(cls, null); } /** * Method that can be called to see if this serializer provider * can find a serializer for an instance of given class. *<p> * Note that no Exceptions are thrown, including unchecked ones: * implementations are to swallow exceptions if necessary. */ public boolean hasSerializerFor(Class<?> cls, AtomicReference<Throwable> cause) { try { JsonSerializer<?> ser = _findExplicitUntypedSerializer(cls); return (ser != null); } catch (JsonMappingException e) { if (cause != null) { cause.set(e); } } catch (RuntimeException e) { if (cause == null) { // earlier behavior throw e; } cause.set(e); } return false; } /* /******************************************************** /* Access to caching details /******************************************************** */ /** * Method that can be used to determine how many serializers this * provider is caching currently * (if it does caching: default implementation does) * Exact count depends on what kind of serializers get cached; * default implementation caches all serializers, including ones that

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> tatu: We may actually want to use equality, * instead of identity... so: */ if (isEnabled(SerializationFeature.USE_EQUALITY_FOR_OBJECT_ID)) { return new HashMap<Object,WritableObjectId>(); } return new IdentityHashMap<Object,WritableObjectId>(); } /* /********************************************************** /* Factory method impls /********************************************************** */ @Override public JsonSerializer<Object> serializerInstance(Annotated annotated, Object serDef) throws JsonMappingException { if (serDef == null) { return null; } JsonSerializer<?> ser; if (serDef instanceof JsonSerializer) { ser = (JsonSerializer<?>) serDef; } else { /* Alas, there's no way to force return type of "either class * X or Y" -- need to throw an exception after the fact */ if (!(serDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned serializer definition of type " +serDef.getClass().getName()+"; expected type JsonSerializer or Class<JsonSerializer> instead"); } Class<?> serClass = (Class<?>)serDef; // there are some known "no class" markers to consider too: if (serClass == JsonSerializer.None.class || ClassUtil.isBogusClass(serClass)) { return null; } if (!JsonSerializer.class.isAssignableFrom(serClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class " +serClass.getName()+"; expected Class<JsonSerializer>"); } HandlerInstantiator hi = _config.getHandlerInstantiator(); ser = (hi == null) ? null : hi.serializerInstance(_config, annotated, serClass); if (ser == null) { ser = (JsonSerializer<?>) ClassUtil.createInstance(serClass, _config.canOverrideAccessModifiers()); } } return (JsonSerializer<Object>) _handleResolvable(ser); } /* /********************************************************** /* Helper classes /********************************************************** */ /** * Concrete implementation that defines factory method(s), * defined as final. */ public final static class Impl extends DefaultSerializerProvider { private static final long serialVersionUID = 1L; public Impl() { super(); } protected Impl(SerializerProvider src, SerializationConfig config

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> need to * know creators. */ BeanDescription beanDesc = config.introspect(type); // Ok, so: can we find T(String) constructor? Constructor<?> ctor = beanDesc.findSingleArgConstructor(String.class); if (ctor != null) { if (config.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(ctor); } return new StdKeyDeserializer.StringCtorKeyDeserializer(ctor); } /* or if not, "static T valueOf(String)" (or equivalent marked * with @JsonCreator annotation?) */ Method m = beanDesc.findFactoryMethod(String.class); if (m != null){ if (config.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(m); } return new StdKeyDeserializer.StringFactoryKeyDeserializer(m); } // nope, no such luck... return null; } /* /********************************************************** /* KeyDeserializers implementation /********************************************************** */ @Override public KeyDeserializer findKeyDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { Class<?> raw = type.getRawClass(); // 23-Apr-2013, tatu: Map primitive types, just in case one was given if (raw.isPrimitive()) { raw = ClassUtil.wrapperType(raw); } return StdKeyDeserializer.forType(raw); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.IOException; import java.lang.reflect.Type; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Locale; import java.util.TimeZone; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.introspect.Annotated; import com.fasterxml.jackson.databind.jsonFormatVisitors.*; import com.fasterxml.jackson.databind.ser.ContextualSerializer; import com.fasterxml.jackson.databind.util.StdDateFormat; public abstract class DateTimeSerializerBase<T> extends StdScalarSerializer<T> implements ContextualSerializer { /** * Flag that indicates that serialization must be done as the * Java timestamp, regardless of other settings. */ protected final Boolean _useTimestamp; /** * Specific format to use, if not default format: non null value * also indicates that serialization is to be done as JSON String, * not numeric timestamp, unless {@link #_useTimestamp} is true. */ protected final DateFormat _customFormat; protected DateTimeSerializerBase(Class<T> type, Boolean useTimestamp, DateFormat customFormat) { super(type); _useTimestamp = useTimestamp; _customFormat = customFormat; } public abstract DateTimeSerializerBase<T> withFormat(Boolean timestamp, DateFormat customFormat); @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { if (property != null) { JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat((Annotated)property.getMember()); if (format != null) { // Simple case first: serialize as numeric timestamp? if (format.getShape().isNumeric()) { return withFormat(Boolean.TRUE, null); } Boolean asNumber = (format.getShape() == JsonFormat.Shape.STRING) ? Boolean.FALSE : null; // If not, do we

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> have a pattern? TimeZone tz = format.getTimeZone(); if (format.hasPattern()) { String pattern = format.getPattern(); final Locale loc = format.hasLocale() ? format.getLocale() : prov.getLocale(); SimpleDateFormat df = new SimpleDateFormat(pattern, loc); if (tz == null) { tz = prov.getTimeZone(); } df.setTimeZone(tz); return withFormat(asNumber, df); } // If not, do we at least have a custom timezone? if (tz != null) { DateFormat df = prov.getConfig().getDateFormat(); // one shortcut: with our custom format, can simplify handling a bit if (df.getClass() == StdDateFormat.class) { final Locale loc = format.hasLocale() ? format.getLocale() : prov.getLocale(); df = StdDateFormat.getISO8601Format(tz, loc); } else { // otherwise need to clone, re-set timezone: df = (DateFormat) df.clone(); df.setTimeZone(tz); } return withFormat(asNumber, df); } } } return this; } /* /********************************************************** /* Accessors /********************************************************** */ @Override public boolean isEmpty(T value) { // let's assume "null date" (timestamp 0) qualifies for empty return (value == null) || (_timestamp(value) == 0L); } protected abstract long _timestamp(T value); @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { //todo: (ryan) add a format for the date in the schema? return createSchemaNode(_asTimestamp(provider) ? "number" : "string", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { _acceptJsonFormatVisitor(visitor, typeHint, _asTimestamp(visitor.getProvider())); } /* /********************************************************** /* Actual serialization /********************************************************** */ @Override public abstract void serialize(T value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException; /* /********************************************************** /* Helper methods /********************************************************** */ protected

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> boolean _asTimestamp(SerializerProvider provider) { if (_useTimestamp != null) { return _useTimestamp.booleanValue(); } if (_customFormat == null) { if (provider != null) { return provider.isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); } // 12-Jun-2014, tatu: Is it legal not to have provider? Was NPE:ing earlier so leave a check throw new IllegalArgumentException("Null 'provider' passed for "+handledType().getName()); } return false; } protected void _acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint, boolean asNumber) throws JsonMappingException { if (asNumber) { JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint); if (v2 != null) { v2.numberType(JsonParser.NumberType.LONG); v2.format(JsonValueFormat.UTC_MILLISEC); } } else { JsonStringFormatVisitor v2 = visitor.expectStringFormat(typeHint); if (v2 != null) { v2.format(JsonValueFormat.DATE_TIME); } } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> _method.getGenericReturnType(); } /** * For methods, this returns declared return type, which is only * useful with getters (setters do not usually return anything; * hence "void" type is returned here) */ @Override public Class<?> getRawType() { return _method.getReturnType(); } /** * As per [JACKSON-468], we need to also allow declaration of local * type bindings; mostly it will allow defining bounds. */ @Override public JavaType getType(TypeBindings bindings) { return getType(bindings, _method.getTypeParameters()); } @Override public final Object call() throws Exception { return _method.invoke(null); } @Override public final Object call(Object[] args) throws Exception { return _method.invoke(null, args); } @Override public final Object call1(Object arg) throws Exception { return _method.invoke(null, arg); } /* /******************************************************** /* AnnotatedMember impl /******************************************************** */ @Override public Class<?> getDeclaringClass() { return _method.getDeclaringClass(); } @Override public Method getMember() { return _method; } @Override public void setValue(Object pojo, Object value) throws IllegalArgumentException { try { _method.invoke(pojo, value); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Failed to setValue() with method " +getFullName()+": "+e.getMessage(), e); } catch (InvocationTargetException e) { throw new IllegalArgumentException("Failed to setValue() with method " +getFullName()+": "+e.getMessage(), e); } } @Override public Object getValue(Object pojo) throws IllegalArgumentException { try { return _method.invoke(pojo); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Failed to getValue() with method " +getFullName()+": "+e.getMessage(), e); } catch (InvocationTargetException e) { throw new IllegalArgumentException("Failed to getValue() with method " +getFullName()+": "+e.getMessage(), e); } } /* /***************************************************** /* Extended API, generic /***************************************************** */ @Override public int getParameterCount() {

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> return getRawParameterTypes().length; } public String getFullName() { return getDeclaringClass().getName() + "#" + getName() + "(" +getParameterCount()+" params)"; } public Class<?>[] getRawParameterTypes() { if (_paramClasses == null) { _paramClasses = _method.getParameterTypes(); } return _paramClasses; } public Type[] getGenericParameterTypes() { return _method.getGenericParameterTypes(); } @Override public Class<?> getRawParameterType(int index) { Class<?>[] types = getRawParameterTypes(); return (index >= types.length) ? null : types[index]; } @Override public Type getGenericParameterType(int index) { Type[] types = _method.getGenericParameterTypes(); return (index >= types.length) ? null : types[index]; } public Class<?> getRawReturnType() { return _method.getReturnType(); } public Type getGenericReturnType() { return _method.getGenericReturnType(); } /** * Helper method that can be used to check whether method returns * a value or not; if return type declared as <code>void</code>, returns * false, otherwise true * * @since 2.4 */ public boolean hasReturnType() { Class<?> rt = getRawReturnType(); return (rt != Void.TYPE && rt != Void.class); } /* /******************************************************** /* Other /******************************************************** */ @Override public String toString() { return "[method "+getFullName()+"]"; } /* /********************************************************** /* JDK serialization handling /********************************************************** */ Object writeReplace() { return new AnnotatedMethod(new Serialization(_method)); } Object readResolve() { Class<?> clazz = _serialization.clazz; try { Method m = clazz.getDeclaredMethod(_serialization.name, _serialization.args); // 06-Oct-2012, tatu: Has "lost" its security override, may need to force back if (!m.isAccessible()) { ClassUtil.checkAndFixAccess(m); } return new AnnotatedMethod(m, null, null); } catch (Exception e) { throw new IllegalArgumentException("Could

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser.std; import java.io.IOException; import java.util.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.ContextualDeserializer; import com.fasterxml.jackson.databind.jsontype.TypeDeserializer; /** * Standard deserializer for {@link EnumSet}s. * <p> * Note: casting within this class is all messed up -- just could not figure out a way * to properly deal with recursive definition of "EnumSet<K extends Enum<K>, V> */ @SuppressWarnings("rawtypes") public class EnumSetDeserializer extends StdDeserializer<EnumSet<?>> implements ContextualDeserializer { private static final long serialVersionUID = 3479455075597887177L; protected final JavaType _enumType; protected final Class<Enum> _enumClass; protected JsonDeserializer<Enum<?>> _enumDeserializer; /* /********************************************************** /* Life-cycle /********************************************************** */ @SuppressWarnings("unchecked" ) public EnumSetDeserializer(JavaType enumType, JsonDeserializer<?> deser) { super(EnumSet.class); _enumType = enumType; _enumClass = (Class<Enum>) enumType.getRawClass(); _enumDeserializer = (JsonDeserializer<Enum<?>>) deser; } public EnumSetDeserializer withDeserializer(JsonDeserializer<?> deser) { if (_enumDeserializer == deser) { return this; } return new EnumSetDeserializer(_enumType, deser); } /** * Because of costs associated with constructing Enum resolvers, * let's cache instances by default. */ @Override public boolean isCachable() { return true; } @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { JsonDeserializer<?> deser = _enumDeserializer; if (deser == null) { deser = ctxt.findContextualValueDeserializer(_enumType, property); } else { // if directly assigned, probably not yet contextual, so: deser = ctxt.handleSecondaryContextualization(deser, property); } return withDeserializer

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>(deser); } /* /********************************************************** /* JsonDeserializer API /********************************************************** */ @SuppressWarnings("unchecked") @Override public EnumSet<?> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { throw ctxt.mappingException(EnumSet.class); } EnumSet result = constructSet(); JsonToken t; try { while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { /* What to do with nulls? Fail or ignore? Fail, for now * (note: would fail if we passed it to EnumDeserializer, too, * but in general nulls should never be passed to non-container * deserializers) */ if (t == JsonToken.VALUE_NULL) { throw ctxt.mappingException(_enumClass); } Enum<?> value = _enumDeserializer.deserialize(jp, ctxt); /* 24-Mar-2012, tatu: As per [JACKSON-810], may actually get nulls; * but EnumSets don't allow nulls so need to skip. */ if (value != null) { result.add(value); } } } catch (Exception e) { // note: pass Object.class, not Object[].class, as we need element type for error info throw JsonMappingException.wrapWithPath(e, Enum.class, result.size()); } return result; } @Override public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException, JsonProcessingException { return typeDeserializer.deserializeTypedFromArray(jp, ctxt); } @SuppressWarnings("unchecked") private EnumSet constructSet() { // superbly ugly... but apparently necessary return EnumSet.noneOf(_enumClass); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.IOException; import java.lang.reflect.Type; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; /** * Serializer used for primitive boolean, as well as java.util.Boolean * wrapper type. *<p> * Since this is one of "native" types, no type information is ever * included on serialization (unlike for most scalar types as of 1.5) */ @JacksonStdImpl public final class BooleanSerializer extends NonTypedScalarSerializerBase<Boolean> { /** * Whether type serialized is primitive (boolean) or wrapper * (java.lang.Boolean); if true, former, if false, latter. */ protected final boolean _forPrimitive; public BooleanSerializer(boolean forPrimitive) { super(Boolean.class); _forPrimitive = forPrimitive; } @Override public void serialize(Boolean value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeBoolean(value.booleanValue()); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("boolean", !_forPrimitive); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { if (visitor != null) { visitor.expectBooleanFormat(typeHint); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> shared (slow) cache /********************************************************** */ public synchronized int size() { return _sharedMap.size(); } /** * Method that checks if the shared (and hence, synchronized) lookup Map might have * untyped serializer for given type. */ public JsonSerializer<Object> untypedValueSerializer(Class<?> type) { synchronized (this) { return _sharedMap.get(new TypeKey(type, false)); } } public JsonSerializer<Object> untypedValueSerializer(JavaType type) { synchronized (this) { return _sharedMap.get(new TypeKey(type, false)); } } public JsonSerializer<Object> typedValueSerializer(JavaType type) { synchronized (this) { return _sharedMap.get(new TypeKey(type, true)); } } public JsonSerializer<Object> typedValueSerializer(Class<?> cls) { synchronized (this) { return _sharedMap.get(new TypeKey(cls, true)); } } /* /********************************************************** /* Methods for adding shared serializer instances /********************************************************** */ /** * Method called if none of lookups succeeded, and caller had to construct * a serializer. If so, we will update the shared lookup map so that it * can be resolved via it next time. */ public void addTypedSerializer(JavaType type, JsonSerializer<Object> ser) { synchronized (this) { if (_sharedMap.put(new TypeKey(type, true), ser) == null) { // let's invalidate the read-only copy, too, to get it updated _readOnlyMap = null; } } } public void addTypedSerializer(Class<?> cls, JsonSerializer<Object> ser) { synchronized (this) { if (_sharedMap.put(new TypeKey(cls, true), ser) == null) { // let's invalidate the read-only copy, too, to get it updated _readOnlyMap = null; } } } public void addAndResolveNonTypedSerializer(Class<?> type, JsonSerializer<Object> ser, SerializerProvider provider) throws JsonMappingException { synchronized (this) { if (_sharedMap.put(new TypeKey(type, false), ser) == null

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>) { // let's invalidate the read-only copy, too, to get it updated _readOnlyMap = null; } /* Finally: some serializers want to do post-processing, after * getting registered (to handle cyclic deps). */ /* 14-May-2011, tatu: As per [JACKSON-570], resolving needs to be done * in synchronized manner; this because while we do need to register * instance first, we also must keep lock until resolution is complete */ if (ser instanceof ResolvableSerializer) { ((ResolvableSerializer) ser).resolve(provider); } } } public void addAndResolveNonTypedSerializer(JavaType type, JsonSerializer<Object> ser, SerializerProvider provider) throws JsonMappingException { synchronized (this) { if (_sharedMap.put(new TypeKey(type, false), ser) == null) { // let's invalidate the read-only copy, too, to get it updated _readOnlyMap = null; } /* Finally: some serializers want to do post-processing, after * getting registered (to handle cyclic deps). */ /* 14-May-2011, tatu: As per [JACKSON-570], resolving needs to be done * in synchronized manner; this because while we do need to register * instance first, we also must keep lock until resolution is complete */ if (ser instanceof ResolvableSerializer) { ((ResolvableSerializer) ser).resolve(provider); } } } /** * Method called by StdSerializerProvider#flushCachedSerializers() to * clear all cached serializers */ public synchronized void flush() { _sharedMap.clear(); } /* /************************************************************** /* Helper class(es) /************************************************************** */ /** * Key that offers two "modes"; one with raw class, as used for * cases were raw class type is available (for example, when using * runtime type); and one with full generics-including. */ public final static class TypeKey { protected int _hashCode; protected Class<?> _class; protected JavaType _type; /** * Indicator of whether serializer stored has a type serializer * wrapper around it

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>); /** * Convenience method for creating a new factory instance with an additional * serializer provider. */ @Override public final SerializerFactory withAdditionalSerializers(Serializers additional) { return withConfig(_factoryConfig.withAdditionalSerializers(additional)); } /** * Convenience method for creating a new factory instance with an additional * key serializer provider. */ @Override public final SerializerFactory withAdditionalKeySerializers(Serializers additional) { return withConfig(_factoryConfig.withAdditionalKeySerializers(additional)); } /** * Convenience method for creating a new factory instance with additional bean * serializer modifier. */ @Override public final SerializerFactory withSerializerModifier(BeanSerializerModifier modifier) { return withConfig(_factoryConfig.withSerializerModifier(modifier)); } /* /********************************************************** /* SerializerFactory impl /********************************************************** */ // Implemented by sub-classes @Override public abstract JsonSerializer<Object> createSerializer(SerializerProvider prov, JavaType type) throws JsonMappingException; @Override @SuppressWarnings("unchecked") public JsonSerializer<Object> createKeySerializer(SerializationConfig config, JavaType keyType, JsonSerializer<Object> defaultImpl) { // We should not need any member method info; at most class annotations for Map type BeanDescription beanDesc = config.introspectClassAnnotations(keyType.getRawClass()); JsonSerializer<?> ser = null; // Minor optimization: to avoid constructing beanDesc, bail out if none registered if (_factoryConfig.hasKeySerializers()) { // Only thing we have here are module-provided key serializers: for (Serializers serializers : _factoryConfig.keySerializers()) { ser = serializers.findSerializer(config, keyType, beanDesc); if (ser != null) { break; } } } if (ser == null) { ser = defaultImpl; if (ser == null) { ser = StdKeySerializers.getStdKeySerializer(keyType); } } // [Issue#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod.modifyKeySerializer(config, keyType, beanDesc, ser); } } return (JsonSerializer

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS><Object>) ser; } /** * Method called to construct a type serializer for values with given declared * base type. This is called for values other than those of bean property * types. */ @Override public TypeSerializer createTypeSerializer(SerializationConfig config, JavaType baseType) { BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass()); AnnotatedClass ac = bean.getClassInfo(); AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType); /* Ok: if there is no explicit type info handler, we may want to * use a default. If so, config object knows what to use. */ Collection<NamedType> subtypes = null; if (b == null) { b = config.getDefaultTyper(baseType); } else { subtypes = config.getSubtypeResolver().collectAndResolveSubtypes(ac, config, ai); } if (b == null) { return null; } return b.buildTypeSerializer(config, baseType, subtypes); } /* /********************************************************** /* Additional API for other core classes /********************************************************** */ protected abstract Iterable<Serializers> customSerializers(); /* /********************************************************** /* Overridable secondary serializer accessor methods /********************************************************** */ /** * Method that will use fast lookup (and identity comparison) methods to * see if we know serializer to use for given type. */ protected final JsonSerializer<?> findSerializerByLookup(JavaType type, SerializationConfig config, BeanDescription beanDesc, boolean staticTyping) { Class<?> raw = type.getRawClass(); String clsName = raw.getName(); JsonSerializer<?> ser = _concrete.get(clsName); if (ser == null) { Class<? extends JsonSerializer<?>> serClass = _concreteLazy.get(clsName); if (serClass != null) { try { return serClass.newInstance(); } catch (Exception e) { throw new IllegalStateException("Failed to instantiate standard serializer (of type "+serClass.getName()+"): " +e.getMessage(), e); } } } return ser; } /** * Method called to see if one

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> of primary per-class annotations * (or related, like implementing of {@link JsonSerializable}) * determines the serializer to use. *<p> * Currently handles things like: *<ul> * <li>If type implements {@link JsonSerializable}, use that * </li> * <li>If type has {@link com.fasterxml.jackson.annotation.JsonValue} annotation (or equivalent), build serializer * based on that property * </li> *</ul> * * @since 2.0 */ protected final JsonSerializer<?> findSerializerByAnnotations(SerializerProvider prov, JavaType type, BeanDescription beanDesc) throws JsonMappingException { Class<?> raw = type.getRawClass(); // First: JsonSerializable? if (JsonSerializable.class.isAssignableFrom(raw)) { return SerializableSerializer.instance; } // Second: @JsonValue for any type AnnotatedMethod valueMethod = beanDesc.findJsonValueMethod(); if (valueMethod != null) { Method m = valueMethod.getAnnotated(); if (prov.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(m); } JsonSerializer<Object> ser = findSerializerFromAnnotation(prov, valueMethod); return new JsonValueSerializer(m, ser); } // No well-known annotations... return null; } /** * Method for checking if we can determine serializer to use based on set of * known primary types, checking for set of known base types (exact matches * having been compared against with <code>findSerializerByLookup</code>). * This does not include "secondary" interfaces, but * mostly concrete or abstract base classes. */ protected final JsonSerializer<?> findSerializerByPrimaryType(SerializerProvider prov, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { Class<?> raw = type.getRawClass(); // Then check for optional/external serializers [JACKSON-386] JsonSerializer<?> ser = findOptionalStdSerializer(prov, type, beanDesc, staticTyping); if (ser != null) { return ser; } if (Calendar.class.isAssignableFrom(raw)) { return CalendarSerializer.instance; } if (java.util.Date.class.isAssignableFrom(

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>raw)) { return DateSerializer.instance; } if (ByteBuffer.class.isAssignableFrom(raw)) { return new ByteBufferSerializer(); } if (InetAddress.class.isAssignableFrom(raw)) { return new InetAddressSerializer(); } if (InetSocketAddress.class.isAssignableFrom(raw)) { return new InetSocketAddressSerializer(); } if (TimeZone.class.isAssignableFrom(raw)) { return new TimeZoneSerializer(); } if (java.nio.charset.Charset.class.isAssignableFrom(raw)) { return ToStringSerializer.instance; } if (Number.class.isAssignableFrom(raw)) { // 21-May-2014, tatu: Couple of alternatives actually JsonFormat.Value format = beanDesc.findExpectedFormat(null); if (format != null) { switch (format.getShape()) { case STRING: return ToStringSerializer.instance; case OBJECT: // need to bail out to let it be serialized as POJO case ARRAY: // or, I guess ARRAY; otherwise no point in speculating return null; default: } } return NumberSerializer.instance; } if (Enum.class.isAssignableFrom(raw)) { return buildEnumSerializer(prov.getConfig(), type, beanDesc); } return null; } /** * Overridable method called after checking all other types. * * @since 2.2 */ protected JsonSerializer<?> findOptionalStdSerializer(SerializerProvider prov, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { return OptionalHandlerFactory.instance.findSerializer(prov.getConfig(), type, beanDesc); } /** * Reflection-based serialized find method, which checks if * given class implements one of recognized "add-on" interfaces. * Add-on here means a role that is usually or can be a secondary * trait: for example, * bean classes may implement {@link Iterable}, but their main * function is usually something else. The reason for */ protected final JsonSerializer<?> findSerializerByAddonType(SerializationConfig config, JavaType javaType, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { Class<?> type = javaType.getRawClass(); // These need to be in decreasing order

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> of specificity... if (Iterator.class.isAssignableFrom(type)) { return buildIteratorSerializer(config, javaType, beanDesc, staticTyping); } if (Iterable.class.isAssignableFrom(type)) { return buildIterableSerializer(config, javaType, beanDesc, staticTyping); } if (CharSequence.class.isAssignableFrom(type)) { return ToStringSerializer.instance; } return null; } /** * Helper method called to check if a class or method * has an annotation * (@link com.fasterxml.jackson.databind.annotation.JsonSerialize#using) * that tells the class to use for serialization. * Returns null if no such annotation found. */ @SuppressWarnings("unchecked") protected JsonSerializer<Object> findSerializerFromAnnotation(SerializerProvider prov, Annotated a) throws JsonMappingException { Object serDef = prov.getAnnotationIntrospector().findSerializer(a); if (serDef == null) { return null; } JsonSerializer<Object> ser = prov.serializerInstance(a, serDef); // One more thing however: may need to also apply a converter: return (JsonSerializer<Object>) findConvertingSerializer(prov, a, ser); } /** * Helper method that will check whether given annotated entity (usually class, * but may also be a property accessor) indicates that a {@link Converter} is to * be used; and if so, to construct and return suitable serializer for it. * If not, will simply return given serializer as is. */ protected JsonSerializer<?> findConvertingSerializer(SerializerProvider prov, Annotated a, JsonSerializer<?> ser) throws JsonMappingException { Converter<Object,Object> conv = findConverter(prov, a); if (conv == null) { return ser; } JavaType delegateType = conv.getOutputType(prov.getTypeFactory()); return new StdDelegatingSerializer(conv, delegateType, ser); } protected Converter<Object,Object> findConverter(SerializerProvider prov, Annotated a) throws JsonMappingException { Object convDef = prov.getAnnotationIntrospector().findSerializationConverter(a); if (convDef == null) { return null; } return prov.converterInstance(a, convDef); } /*

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> /********************************************************** /* Factory methods, container types: /********************************************************** */ /** * @since 2.1 */ protected JsonSerializer<?> buildContainerSerializer(SerializerProvider prov, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { final SerializationConfig config = prov.getConfig(); /* [Issue#23], 15-Mar-2013, tatu: must force static handling of root value type, * with just one important exception: if value type is "untyped", let's * leave it as is; no clean way to make it work. */ if (!staticTyping && type.useStaticType()) { if (!type.isContainerType() || type.getContentType().getRawClass() != Object.class) { staticTyping = true; } } // Let's see what we can learn about element/content/value type, type serializer for it: JavaType elementType = type.getContentType(); TypeSerializer elementTypeSerializer = createTypeSerializer(config, elementType); // if elements have type serializer, can not force static typing: if (elementTypeSerializer != null) { staticTyping = false; } JsonSerializer<Object> elementValueSerializer = _findContentSerializer(prov, beanDesc.getClassInfo()); if (type.isMapLikeType()) { // implements java.util.Map MapLikeType mlt = (MapLikeType) type; /* 29-Sep-2012, tatu: This is actually too early to (try to) find * key serializer from property annotations, and can lead to caching * issues (see [Issue#75]). Instead, must be done from 'createContextual()' call. * But we do need to check class annotations. */ JsonSerializer<Object> keySerializer = _findKeySerializer(prov, beanDesc.getClassInfo()); if (mlt.isTrueMapType()) { return buildMapSerializer(config, (MapType) mlt, beanDesc, staticTyping, keySerializer, elementTypeSerializer, elementValueSerializer); } // Only custom serializers may be available: for (Serializers serializers : customSerializers()) { MapLikeType mlType = (MapLikeType) type; JsonSerializer<?>

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> ser = serializers.findMapLikeSerializer(config, mlType, beanDesc, keySerializer, elementTypeSerializer, elementValueSerializer); if (ser != null) { // [Issue#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod.modifyMapLikeSerializer(config, mlType, beanDesc, ser); } } return ser; } } return null; } if (type.isCollectionLikeType()) { CollectionLikeType clt = (CollectionLikeType) type; if (clt.isTrueCollectionType()) { return buildCollectionSerializer(config, (CollectionType) clt, beanDesc, staticTyping, elementTypeSerializer, elementValueSerializer); } CollectionLikeType clType = (CollectionLikeType) type; // Only custom variants for this: for (Serializers serializers : customSerializers()) { JsonSerializer<?> ser = serializers.findCollectionLikeSerializer(config, clType, beanDesc, elementTypeSerializer, elementValueSerializer); if (ser != null) { // [Issue#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod.modifyCollectionLikeSerializer(config, clType, beanDesc, ser); } } return ser; } } // fall through either way (whether shape dictates serialization as POJO or not) return null; } if (type.isArrayType()) { return buildArraySerializer(config, (ArrayType) type, beanDesc, staticTyping, elementTypeSerializer, elementValueSerializer); } return null; } /** * Helper method that handles configuration details when constructing serializers for * {@link java.util.List} types that support efficient by-index access * * @since 2.1 */ protected JsonSerializer<?> buildCollectionSerializer(SerializationConfig config, CollectionType type, BeanDescription beanDesc, boolean staticTyping, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) throws JsonMappingException { JsonSerializer<?> ser = null; // Module-provided custom collection serializers? for (Serial

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> ser = mod.modifyCollectionSerializer(config, type, beanDesc, ser); } } return ser; } /* /********************************************************** /* Factory methods, for Collections /********************************************************** */ protected boolean isIndexedList(Class<?> cls) { return RandomAccess.class.isAssignableFrom(cls); } public ContainerSerializer<?> buildIndexedListSerializer(JavaType elemType, boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) { return new IndexedListSerializer(elemType, staticTyping, vts, null, valueSerializer); } public ContainerSerializer<?> buildCollectionSerializer(JavaType elemType, boolean staticTyping, TypeSerializer vts, JsonSerializer<Object> valueSerializer) { return new CollectionSerializer(elemType, staticTyping, vts, null, valueSerializer); } public JsonSerializer<?> buildEnumSetSerializer(JavaType enumType) { return new EnumSetSerializer(enumType, null); } /* /********************************************************** /* Factory methods, for Maps /********************************************************** */ /** * Helper method that handles configuration details when constructing serializers for * {@link java.util.Map} types. */ protected JsonSerializer<?> buildMapSerializer(SerializationConfig config, MapType type, BeanDescription beanDesc, boolean staticTyping, JsonSerializer<Object> keySerializer, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) throws JsonMappingException { JsonSerializer<?> ser = null; for (Serializers serializers : customSerializers()) { ser = serializers.findMapSerializer(config, type, beanDesc, keySerializer, elementTypeSerializer, elementValueSerializer); if (ser != null) { break; } } if (ser == null) { if (EnumMap.class.isAssignableFrom(type.getRawClass())) { JavaType keyType = type.getKeyType(); // Need to find key enum values... EnumValues enums = null; if (keyType.isEnumType()) { // non-enum if we got it as type erased class (from instance) @SuppressWarnings("unchecked") Class<Enum<?>> enumClass = (Class<Enum<?>>) keyType.getRawClass(); enums = EnumValues.construct(config, enumClass); } ser = new EnumMapSerializer(type.getContentType(), static

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Typing, enums, elementTypeSerializer, elementValueSerializer); } else { Object filterId = findFilterId(config, beanDesc); ser = MapSerializer.construct(config.getAnnotationIntrospector().findPropertiesToIgnore(beanDesc.getClassInfo()), type, staticTyping, elementTypeSerializer, keySerializer, elementValueSerializer, filterId); } } // [Issue#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod.modifyMapSerializer(config, type, beanDesc, ser); } } return ser; } /* /********************************************************** /* Factory methods, for Arrays /********************************************************** */ /** * Helper method that handles configuration details when constructing serializers for * <code>Object[]</code> (and subtypes, except for String). */ protected JsonSerializer<?> buildArraySerializer(SerializationConfig config, ArrayType type, BeanDescription beanDesc, boolean staticTyping, TypeSerializer elementTypeSerializer, JsonSerializer<Object> elementValueSerializer) throws JsonMappingException { JsonSerializer<?> ser = null; // Module-provided custom collection serializers? for (Serializers serializers : customSerializers()) { ser = serializers.findArraySerializer(config, type, beanDesc, elementTypeSerializer, elementValueSerializer); if (ser != null) { break; } } if (ser == null) { Class<?> raw = type.getRawClass(); // Important: do NOT use standard serializers if non-standard element value serializer specified if (elementValueSerializer == null || ClassUtil.isJacksonStdImpl(elementValueSerializer)) { if (String[].class == raw) { ser = StringArraySerializer.instance; } else { // other standard types? ser = StdArraySerializers.findStandardImpl(raw); } } if (ser == null) { ser = new ObjectArraySerializer(type.getContentType(), staticTyping, elementTypeSerializer, elementValueSerializer); } } // [Issue#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>.modifyArraySerializer(config, type, beanDesc, ser); } } return ser; } /* /********************************************************** /* Factory methods, for non-container types /********************************************************** */ protected JsonSerializer<?> buildIteratorSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { // if there's generic type, it'll be the first contained type JavaType valueType = type.containedType(0); if (valueType == null) { valueType = TypeFactory.unknownType(); } TypeSerializer vts = createTypeSerializer(config, valueType); return new IteratorSerializer(valueType, staticTyping, vts, null); } protected JsonSerializer<?> buildIterableSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { // if there's generic type, it'll be the first contained type JavaType valueType = type.containedType(0); if (valueType == null) { valueType = TypeFactory.unknownType(); } TypeSerializer vts = createTypeSerializer(config, valueType); return new IterableSerializer(valueType, staticTyping, vts, null); } protected JsonSerializer<?> buildEnumSerializer(SerializationConfig config, JavaType type, BeanDescription beanDesc) throws JsonMappingException { /* As per [Issue#24], may want to use alternate shape, serialize as JSON Object. * Challenge here is that EnumSerializer does not know how to produce * POJO style serialization, so we must handle that special case separately; * otherwise pass it to EnumSerializer. */ JsonFormat.Value format = beanDesc.findExpectedFormat(null); if (format != null && format.getShape() == JsonFormat.Shape.OBJECT) { // one special case: suppress serialization of "getDeclaringClass()"... ((BasicBeanDescription) beanDesc).removeProperty("declaringClass"); // returning null will mean that eventually BeanSerializer gets constructed return null; } @SuppressWarnings("unchecked") Class<Enum<?>> enumClass = (Class<Enum<?>>) type.getRawClass(); JsonSerializer<?> ser = EnumSerializer.construct(enumClass, config, beanDesc, format); // [Issue#120]:

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>widenContentsBy(cc); } catch (IllegalArgumentException iae) { throw new IllegalArgumentException("Failed to narrow content type "+type+" with content-type annotation ("+cc.getName()+"): "+iae.getMessage()); } } } return type; } /** * Helper method called to try to find whether there is an annotation in the * class that indicates key serializer to use. * If so, will try to instantiate key serializer and return it; otherwise returns null. */ protected JsonSerializer<Object> _findKeySerializer(SerializerProvider prov, Annotated a) throws JsonMappingException { AnnotationIntrospector intr = prov.getAnnotationIntrospector(); Object serDef = intr.findKeySerializer(a); if (serDef != null) { return prov.serializerInstance(a, serDef); } return null; } /** * Helper method called to try to find whether there is an annotation in the * class that indicates content ("value") serializer to use. * If so, will try to instantiate key serializer and return it; otherwise returns null. */ protected JsonSerializer<Object> _findContentSerializer(SerializerProvider prov, Annotated a) throws JsonMappingException { AnnotationIntrospector intr = prov.getAnnotationIntrospector(); Object serDef = intr.findContentSerializer(a); if (serDef != null) { return prov.serializerInstance(a, serDef); } return null; } /** * Method called to find filter that is configured to be used with bean * serializer being built, if any. */ protected Object findFilterId(SerializationConfig config, BeanDescription beanDesc) { return config.getAnnotationIntrospector().findFilterId((Annotated)beanDesc.getClassInfo()); } /** * Helper method to check whether global settings and/or class * annotations for the bean class indicate that static typing * (declared types) should be used for properties. * (instead of dynamic runtime types). * * @since 2.1 (earlier had variant with additional 'property' parameter) */ protected boolean usesStaticTyping(SerializationConfig config, BeanDescription beanDesc, TypeSerializer typeSer) { /* 16-Aug-2010, tatu: If there is

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser; import com.fasterxml.jackson.databind.*; /** * Interface that defines API for simple extensions that can provide additional deserializers * for deserializer Map keys of various types, from JSON property names. * Access is by a single callback method; instance is to either return * a configured {@link KeyDeserializer} for specified type, or null to indicate that it * does not support handling of the type. In latter case, further calls can be made * for other providers; in former case returned key deserializer is used for handling of * key instances of specified type. */ public interface KeyDeserializers { public KeyDeserializer findKeyDeserializer(JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> * 'setter' method signature and/or type annotations * * @throws JsonMappingException if there are fatal problems with * accessing suitable deserializer; including that of not * finding any serializer */ public JsonDeserializer<Object> findValueDeserializer(DeserializationContext ctxt, DeserializerFactory factory, JavaType propertyType) throws JsonMappingException { JsonDeserializer<Object> deser = _findCachedDeserializer(propertyType); if (deser == null) { // If not, need to request factory to construct (or recycle) deser = _createAndCacheValueDeserializer(ctxt, factory, propertyType); if (deser == null) { /* Should we let caller handle it? Let's have a helper method * decide it; can throw an exception, or return a valid * deserializer */ deser = _handleUnknownValueDeserializer(propertyType); } } return deser; } /** * Method called to get hold of a deserializer to use for deserializing * keys for {@link java.util.Map}. * * @throws JsonMappingException if there are fatal problems with * accessing suitable key deserializer; including that of not * finding any serializer */ public KeyDeserializer findKeyDeserializer(DeserializationContext ctxt, DeserializerFactory factory, JavaType type) throws JsonMappingException { KeyDeserializer kd = factory.createKeyDeserializer(ctxt, type); if (kd == null) { // if none found, need to use a placeholder that'll fail return _handleUnknownKeyDeserializer(type); } // First: need to resolve? if (kd instanceof ResolvableDeserializer) { ((ResolvableDeserializer) kd).resolve(ctxt); } return kd; } /** * Method called to find out whether provider would be able to find * a deserializer for given type, using a root reference (i.e. not * through fields or membership in an array or collection) */ public boolean hasValueDeserializerFor(DeserializationContext ctxt, DeserializerFactory factory, JavaType type) throws JsonMappingException { /* Note: mostly copied from findValueDeserializer, except for * handling of unknown types */ JsonDeserializer<Object> deser = _findCachedDeserializer(type); if (deser == null

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>) { deser = _createAndCacheValueDeserializer(ctxt, factory, type); } return (deser != null); } /* /********************************************************** /* Helper methods that handle cache lookups /********************************************************** */ protected JsonDeserializer<Object> _findCachedDeserializer(JavaType type) { if (type == null) { throw new IllegalArgumentException("Null JavaType passed"); } return _cachedDeserializers.get(type); } /** * Method that will try to create a deserializer for given type, * and resolve and cache it if necessary * * @param ctxt Currently active deserialization context * @param type Type of property to deserialize */ protected JsonDeserializer<Object>_createAndCacheValueDeserializer(DeserializationContext ctxt, DeserializerFactory factory, JavaType type) throws JsonMappingException { /* Only one thread to construct deserializers at any given point in time; * limitations necessary to ensure that only completely initialized ones * are visible and used. */ synchronized (_incompleteDeserializers) { // Ok, then: could it be that due to a race condition, deserializer can now be found? JsonDeserializer<Object> deser = _findCachedDeserializer(type); if (deser != null) { return deser; } int count = _incompleteDeserializers.size(); // Or perhaps being resolved right now? if (count > 0) { deser = _incompleteDeserializers.get(type); if (deser != null) { return deser; } } // Nope: need to create and possibly cache try { return _createAndCache2(ctxt, factory, type); } finally { // also: any deserializers that have been created are complete by now if (count == 0 && _incompleteDeserializers.size() > 0) { _incompleteDeserializers.clear(); } } } } /** * Method that handles actual construction (via factory) and caching (both * intermediate and eventual) */ protected JsonDeserializer<Object> _createAndCache2(DeserializationContext ctxt, DeserializerFactory factory, JavaType type) throws JsonMappingException { JsonDeserializer<Object> deser; try { deser = _createDeserializer(ctxt,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> factory, type); } catch (IllegalArgumentException iae) { /* We better only expose checked exceptions, since those * are what caller is expected to handle */ throw new JsonMappingException(iae.getMessage(), null, iae); } if (deser == null) { return null; } /* cache resulting deserializer? always true for "plain" BeanDeserializer * (but can be re-defined for sub-classes by using @JsonCachable!) */ // 08-Jun-2010, tatu: Related to [JACKSON-296], need to avoid caching MapSerializers... so: boolean isResolvable = (deser instanceof ResolvableDeserializer); boolean addToCache = deser.isCachable(); /* we will temporarily hold on to all created deserializers (to * handle cyclic references, and possibly reuse non-cached * deserializers (list, map)) */ /* 07-Jun-2010, tatu: Danger: [JACKSON-296] was caused by accidental * resolution of a reference -- couple of ways to prevent this; * either not add Lists or Maps, or clear references eagerly. * Let's actually do both; since both seem reasonable. */ /* Need to resolve? Mostly done for bean deserializers; required for * resolving cyclic references. */ if (isResolvable) { _incompleteDeserializers.put(type, deser); ((ResolvableDeserializer)deser).resolve(ctxt); _incompleteDeserializers.remove(type); } if (addToCache) { _cachedDeserializers.put(type, deser); } return deser; } /* /********************************************************** /* Helper methods for actual construction of deserializers /********************************************************** */ /** * Method that does the heavy lifting of checking for per-type annotations, * find out full type, and figure out which actual factory method * to call. */ @SuppressWarnings("unchecked") protected JsonDeserializer<Object> _createDeserializer(DeserializationContext ctxt, DeserializerFactory factory, JavaType type) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); // First things first: do we need to use

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> abstract type mapping? if (type.isAbstract() || type.isMapLikeType() || type.isCollectionLikeType()) { type = factory.mapAbstractType(config, type); } BeanDescription beanDesc = config.introspect(type); // Then: does type define explicit deserializer to use, with annotation(s)? JsonDeserializer<Object> deser = findDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo()); if (deser != null) { return deser; } // If not, may have further type-modification annotations to check: JavaType newType = modifyTypeByAnnotation(ctxt, beanDesc.getClassInfo(), type); if (newType != type) { type = newType; beanDesc = config.introspect(newType); } // We may also have a Builder type to consider... Class<?> builder = beanDesc.findPOJOBuilder(); if (builder != null) { return (JsonDeserializer<Object>) factory.createBuilderBasedDeserializer( ctxt, type, beanDesc, builder); } // Or perhaps a Converter? Converter<Object,Object> conv = beanDesc.findDeserializationConverter(); if (conv == null) { // nope, just construct in normal way return (JsonDeserializer<Object>) _createDeserializer2(ctxt, factory, type, beanDesc); } // otherwise need to do bit of introspection JavaType delegateType = conv.getInputType(ctxt.getTypeFactory()); // One more twist, as per [Issue#288]; probably need to get new BeanDesc if (!delegateType.hasRawClass(type.getRawClass())) { beanDesc = config.introspect(delegateType); } return new StdDelegatingDeserializer<Object>(conv, delegateType, _createDeserializer2(ctxt, factory, delegateType, beanDesc)); } protected JsonDeserializer<?> _createDeserializer2(DeserializationContext ctxt, DeserializerFactory factory, JavaType type, BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); // If not, let's see which factory method to use: if (type.isEnumType()) { return factory.createEnumDeserializer(ctxt, type, beanDesc); } if (type.isContainerType

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>()) { if (type.isArrayType()) { return factory.createArrayDeserializer(ctxt, (ArrayType) type, beanDesc); } if (type.isMapLikeType()) { MapLikeType mlt = (MapLikeType) type; if (mlt.isTrueMapType()) { return factory.createMapDeserializer(ctxt,(MapType) mlt, beanDesc); } return factory.createMapLikeDeserializer(ctxt, mlt, beanDesc); } if (type.isCollectionLikeType()) { /* 03-Aug-2012, tatu: As per [Issue#40], one exception is if shape * is to be Shape.OBJECT. Ideally we'd determine it bit later on * (to allow custom handler checks), but that won't work for other * reasons. So do it here. */ JsonFormat.Value format = beanDesc.findExpectedFormat(null); if (format == null || format.getShape() != JsonFormat.Shape.OBJECT) { CollectionLikeType clt = (CollectionLikeType) type; if (clt.isTrueCollectionType()) { return factory.createCollectionDeserializer(ctxt, (CollectionType) clt, beanDesc); } return factory.createCollectionLikeDeserializer(ctxt, clt, beanDesc); } } } if (JsonNode.class.isAssignableFrom(type.getRawClass())) { return factory.createTreeDeserializer(config, type, beanDesc); } return factory.createBeanDeserializer(ctxt, type, beanDesc); } /** * Helper method called to check if a class or method * has annotation that tells which class to use for deserialization. * Returns null if no such annotation found. */ protected JsonDeserializer<Object> findDeserializerFromAnnotation(DeserializationContext ctxt, Annotated ann) throws JsonMappingException { Object deserDef = ctxt.getAnnotationIntrospector().findDeserializer(ann); if (deserDef == null) { return null; } JsonDeserializer<Object> deser = ctxt.deserializerInstance(ann, deserDef); // One more thing however: may need to also apply a converter: return findConvertingDeserializer(ctxt, ann, deser); } /** * Helper method that will

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> check whether given annotated entity (usually class, * but may also be a property accessor) indicates that a {@link Converter} is to * be used; and if so, to construct and return suitable serializer for it. * If not, will simply return given serializer as is. */ protected JsonDeserializer<Object> findConvertingDeserializer(DeserializationContext ctxt, Annotated a, JsonDeserializer<Object> deser) throws JsonMappingException { Converter<Object,Object> conv = findConverter(ctxt, a); if (conv == null) { return deser; } JavaType delegateType = conv.getInputType(ctxt.getTypeFactory()); return (JsonDeserializer<Object>) new StdDelegatingDeserializer<Object>(conv, delegateType, deser); } protected Converter<Object,Object> findConverter(DeserializationContext ctxt, Annotated a) throws JsonMappingException { Object convDef = ctxt.getAnnotationIntrospector().findDeserializationConverter(a); if (convDef == null) { return null; } return ctxt.converterInstance(a, convDef); } /** * Method called to see if given method has annotations that indicate * a more specific type than what the argument specifies. * If annotations are present, they must specify compatible Class; * instance of which can be assigned using the method. This means * that the Class has to be raw class of type, or its sub-class * (or, implementing class if original Class instance is an interface). * * @param a Method or field that the type is associated with * @param type Type derived from the setter argument * * @return Original type if no annotations are present; or a more * specific type derived from it if type annotation(s) was found * * @throws JsonMappingException if invalid annotation is found */ private JavaType modifyTypeByAnnotation(DeserializationContext ctxt, Annotated a, JavaType type) throws JsonMappingException { // first: let's check class for the instance itself: AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); Class<?> subclass = intr.findDeserializationType(a, type); if (subclass != null) { try { type = type.narrowBy(subclass); } catch (IllegalArgumentException iae) { throw new JsonMapping

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Exception("Failed to narrow type "+type+" with concrete-type annotation (value "+subclass.getName()+"), method '"+a.getName()+"': "+iae.getMessage(), null, iae); } } // then key class if (type.isContainerType()) { Class<?> keyClass = intr.findDeserializationKeyType(a, type.getKeyType()); if (keyClass != null) { // illegal to use on non-Maps if (!(type instanceof MapLikeType)) { throw new JsonMappingException("Illegal key-type annotation: type "+type+" is not a Map(-like) type"); } try { type = ((MapLikeType) type).narrowKey(keyClass); } catch (IllegalArgumentException iae) { throw new JsonMappingException("Failed to narrow key type "+type+" with key-type annotation ("+keyClass.getName()+"): "+iae.getMessage(), null, iae); } } JavaType keyType = type.getKeyType(); /* 21-Mar-2011, tatu: ... and associated deserializer too (unless already assigned) * (not 100% why or how, but this does seem to get called more than once, which * is not good: for now, let's just avoid errors) */ if (keyType != null && keyType.getValueHandler() == null) { Object kdDef = intr.findKeyDeserializer(a); if (kdDef != null) { KeyDeserializer kd = ctxt.keyDeserializerInstance(a, kdDef); if (kd != null) { type = ((MapLikeType) type).withKeyValueHandler(kd); keyType = type.getKeyType(); // just in case it's used below } } } // and finally content class; only applicable to structured types Class<?> cc = intr.findDeserializationContentType(a, type.getContentType()); if (cc != null) { try { type = type.narrowContentsBy(cc); } catch (IllegalArgumentException iae) { throw new JsonMappingException("Failed to narrow content type "+type+" with content-type annotation ("+cc.getName()+"): "+iae.getMessage(), null, iae); } } // ... as well as deserializer for contents:

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> JavaType contentType = type.getContentType(); if (contentType.getValueHandler() == null) { // as with above, avoid resetting (which would trigger exception) Object cdDef = intr.findContentDeserializer(a); if (cdDef != null) { JsonDeserializer<?> cd = null; if (cdDef instanceof JsonDeserializer<?>) { cdDef = (JsonDeserializer<?>) cdDef; } else { Class<?> cdClass = _verifyAsClass(cdDef, "findContentDeserializer", JsonDeserializer.None.class); if (cdClass != null) { cd = ctxt.deserializerInstance(a, cdClass); } } if (cd != null) { type = type.withContentValueHandler(cd); } } } } return type; } private Class<?> _verifyAsClass(Object src, String methodName, Class<?> noneClass) { if (src == null) { return null; } if (!(src instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector."+methodName+"() returned value of type "+src.getClass().getName()+": expected type JsonSerializer or Class<JsonSerializer> instead"); } Class<?> cls = (Class<?>) src; if (cls == noneClass || ClassUtil.isBogusClass(cls)) { return null; } return cls; } /* /********************************************************** /* Overridable error reporting methods /********************************************************** */ protected JsonDeserializer<Object> _handleUnknownValueDeserializer(JavaType type) throws JsonMappingException { /* Let's try to figure out the reason, to give better error * messages */ Class<?> rawClass = type.getRawClass(); if (!ClassUtil.isConcrete(rawClass)) { throw new JsonMappingException("Can not find a Value deserializer for abstract type "+type); } throw new JsonMappingException("Can not find a Value deserializer for type "+type); } protected KeyDeserializer _handleUnknownKeyDeserializer(JavaType type) throws JsonMappingException { throw new JsonMappingException("Can not find a (Map) Key deserializer for type "+type); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Serializer = null; } @SuppressWarnings("unchecked") public StdDelegatingSerializer(Converter<Object,?> converter, JavaType delegateType, JsonSerializer<?> delegateSerializer) { super(delegateType); _converter = converter; _delegateType = delegateType; _delegateSerializer = (JsonSerializer<Object>) delegateSerializer; } /** * Method used for creating resolved contextual instances. Must be * overridden when sub-classing. */ protected StdDelegatingSerializer withDelegate(Converter<Object,?> converter, JavaType delegateType, JsonSerializer<?> delegateSerializer) { if (getClass() != StdDelegatingSerializer.class) { throw new IllegalStateException("Sub-class "+getClass().getName()+" must override 'withDelegate'"); } return new StdDelegatingSerializer(converter, delegateType, delegateSerializer); } /* /********************************************************** /* Contextualization /********************************************************** */ @Override public void resolve(SerializerProvider provider) throws JsonMappingException { if ((_delegateSerializer != null) && (_delegateSerializer instanceof ResolvableSerializer)) { ((ResolvableSerializer) _delegateSerializer).resolve(provider); } } @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { // First: if already got serializer to delegate to, contextualize it: if (_delegateSerializer != null) { if (_delegateSerializer instanceof ContextualSerializer) { JsonSerializer<?> ser = provider.handleSecondaryContextualization(_delegateSerializer, property); if (ser == _delegateSerializer) { return this; } return withDelegate(_converter, _delegateType, ser); } return this; } // Otherwise, need to locate serializer to delegate to. For that we need type information... JavaType delegateType = _delegateType; if (delegateType == null) { delegateType = _converter.getOutputType(provider.getTypeFactory()); } // and then find the thing... return withDelegate(_converter, delegateType, provider.findValueSerializer(delegateType, property)); } /* /********************************************************** /* Accessors /********************************************************** */ protected Converter<Object, ?> getConverter() { return _converter; } @Override public JsonSerializer<?> getDelegatee() { return _delegateSerializer;

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } /* /********************************************************** /* Serialization /********************************************************** */ @Override public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { Object delegateValue = convertValue(value); // should we accept nulls? if (delegateValue == null) { provider.defaultSerializeNull(jgen); return; } _delegateSerializer.serialize(delegateValue, jgen, provider); } @Override public void serializeWithType(Object value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException { /* 03-Oct-2012, tatu: This is actually unlikely to work ok... but for now, * let's give it a chance? */ Object delegateValue = convertValue(value); _delegateSerializer.serializeWithType(delegateValue, jgen, provider, typeSer); } @Override public boolean isEmpty(Object value) { Object delegateValue = convertValue(value); return _delegateSerializer.isEmpty(delegateValue); } /* /********************************************************** /* Schema functionality /********************************************************** */ @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { if (_delegateSerializer instanceof SchemaAware) { return ((SchemaAware) _delegateSerializer).getSchema(provider, typeHint); } return super.getSchema(provider, typeHint); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint, boolean isOptional) throws JsonMappingException { if (_delegateSerializer instanceof SchemaAware) { return ((SchemaAware) _delegateSerializer).getSchema(provider, typeHint, isOptional); } return super.getSchema(provider, typeHint); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { /* 03-Sep-2012, tatu: Not sure if this can be made to really work * properly... but for now, try this: */ _delegateSerializer.acceptJsonFormatVisitor(visitor, typeHint); } /* /********************************************************** /* Overridable methods /********************************************************** */ /**

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>field.getDeclaringClass(); } @Override public Member getMember() { return _field; } @Override public void setValue(Object pojo, Object value) throws IllegalArgumentException { try { _field.set(pojo, value); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Failed to setValue() for field " +getFullName()+": "+e.getMessage(), e); } } @Override public Object getValue(Object pojo) throws IllegalArgumentException { try { return _field.get(pojo); } catch (IllegalAccessException e) { throw new IllegalArgumentException("Failed to getValue() for field " +getFullName()+": "+e.getMessage(), e); } } /* /********************************************************** /* Extended API, generic /********************************************************** */ public String getFullName() { return getDeclaringClass().getName() + "#" + getName(); } public int getAnnotationCount() { return _annotations.size(); } @Override public String toString() { return "[field "+getFullName()+"]"; } /* /********************************************************** /* JDK serialization handling /********************************************************** */ Object writeReplace() { return new AnnotatedField(new Serialization(_field)); } Object readResolve() { Class<?> clazz = _serialization.clazz; try { Field f = clazz.getDeclaredField(_serialization.name); // 06-Oct-2012, tatu: Has "lost" its security override, may need to force back if (!f.isAccessible()) { ClassUtil.checkAndFixAccess(f); } return new AnnotatedField(f, null); } catch (Exception e) { throw new IllegalArgumentException("Could not find method '"+_serialization.name +"' from Class '"+clazz.getName()); } } /** * Helper class that is used as the workaround to persist * Field references. It basically just stores declaring class * and field name. */ private final static class Serialization implements java.io.Serializable { private static final long serialVersionUID = 1L; protected Class<?> clazz; protected String name; public Serialization(Field f) { clazz = f.getDeclaringClass(); name = f.getName(); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>) throws JsonMappingException { /* 29-Sep-2012, tatu: Actually, we need to do much more contextual * checking here since we finally know for sure the property, * and it may have overrides */ JsonSerializer<?> ser = null; JsonSerializer<?> keySer = null; final AnnotationIntrospector intr = provider.getAnnotationIntrospector(); final AnnotatedMember propertyAcc = (property == null) ? null : property.getMember(); // First: if we have a property, may have property-annotation overrides if (propertyAcc != null && intr != null) { Object serDef = intr.findKeySerializer(propertyAcc); if (serDef != null) { keySer = provider.serializerInstance(propertyAcc, serDef); } serDef = intr.findContentSerializer(propertyAcc); if (serDef != null) { ser = provider.serializerInstance(propertyAcc, serDef); } } if (ser == null) { ser = _valueSerializer; } // [Issue#124]: May have a content converter ser = findConvertingContentSerializer(provider, property, ser); if (ser == null) { // 30-Sep-2012, tatu: One more thing -- if explicit content type is annotated, // we can consider it a static case as well. // 20-Aug-2013, tatu: Need to avoid trying to access serializer for java.lang.Object tho if ((_valueTypeIsStatic && _valueType.getRawClass() != Object.class) || hasContentTypeAnnotation(provider, property)) { ser = provider.findValueSerializer(_valueType, property); } } else { ser = provider.handleSecondaryContextualization(ser, property); } if (keySer == null) { keySer = _keySerializer; } if (keySer == null) { keySer = provider.findKeySerializer(_keyType, property); } else { keySer = provider.handleSecondaryContextualization(keySer, property); } HashSet<String> ignored = _ignoredEntries; boolean sortKeys = false; if (intr != null && propertyAcc != null) { String[] more

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>, provider); } else { // [JACKSON-314] skip entries with null values? if (skipNulls && valueElem == null) continue; // One twist: is entry ignorable? If so, skip if (ignored != null && ignored.contains(keyElem)) continue; keySerializer.serialize(keyElem, jgen, provider); } // And then value if (valueElem == null) { provider.defaultSerializeNull(jgen); } else { Class<?> cc = valueElem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { if (_valueType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_valueType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicValueSerializers; } try { serializer.serialize(valueElem, jgen, provider); } catch (Exception e) { // [JACKSON-55] Need to add reference information String keyDesc = ""+keyElem; wrapAndThrow(provider, e, value, keyDesc); } } } } /** * Method called to serialize fields, when the value type is statically known, * so that value serializer is passed and does not need to be fetched from * provider. */ protected void serializeFieldsUsing(Map<?,?> value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException, JsonGenerationException { final JsonSerializer<Object> keySerializer = _keySerializer; final HashSet<String> ignored = _ignoredEntries; final TypeSerializer typeSer = _valueTypeSerializer; final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES); for (Map.Entry<?,?> entry : value.entrySet()) { Object valueElem = entry.getValue(); Object keyElem = entry.getKey(); if (keyElem == null) { provider.findNullKeySerializer(_keyType, _property).serialize(null, jgen, provider); } else { // [JACKSON-314] also may need to skip entries with null values

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> if (skipNulls && valueElem == null) continue; if (ignored != null && ignored.contains(keyElem)) continue; keySerializer.serialize(keyElem, jgen, provider); } if (valueElem == null) { provider.defaultSerializeNull(jgen); } else { try { if (typeSer == null) { ser.serialize(valueElem, jgen, provider); } else { ser.serializeWithType(valueElem, jgen, provider, typeSer); } } catch (Exception e) { // [JACKSON-55] Need to add reference information String keyDesc = ""+keyElem; wrapAndThrow(provider, e, value, keyDesc); } } } } /** * Helper method used when we have a JSON Filter to use for potentially * filtering out Map entries. *<p> * NOTE: initially only called externally, by <code>AnyGetterWriter</code> * * @since 2.3 */ public void serializeFilteredFields(Map<?,?> value, JsonGenerator jgen, SerializerProvider provider, PropertyFilter filter) throws IOException, JsonGenerationException { final HashSet<String> ignored = _ignoredEntries; final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES); PropertySerializerMap serializers = _dynamicValueSerializers; final MapProperty prop = new MapProperty(_valueTypeSerializer); for (Map.Entry<?,?> entry : value.entrySet()) { // First, serialize key final Object keyElem = entry.getKey(); final Object valueElem = entry.getValue(); JsonSerializer<Object> keySer; if (keyElem == null) { keySer = provider.findNullKeySerializer(_keyType, _property); } else { // [JACKSON-314] skip entries with null values? if (skipNulls && valueElem == null) continue; // One twist: is entry ignorable? If so, skip if (ignored != null && ignored.contains(keyElem)) continue; keySer = _keySerializer; } JsonSerializer<Object> valueSer; // And then value if (valueElem == null) { valueSer = provider.getDefaultNullValue

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Serializer(); } else { Class<?> cc = valueElem.getClass(); valueSer = serializers.serializerFor(cc); if (valueSer == null) { if (_valueType.hasGenericTypes()) { valueSer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_valueType, cc), provider); } else { valueSer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicValueSerializers; } } prop.reset(keyElem, valueElem, keySer, valueSer); try { filter.serializeAsField(value, jgen, provider, prop); } catch (Exception e) { // [JACKSON-55] Need to add reference information String keyDesc = ""+keyElem; wrapAndThrow(provider, e, value, keyDesc); } } } protected void serializeTypedFields(Map<?,?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { final JsonSerializer<Object> keySerializer = _keySerializer; JsonSerializer<Object> prevValueSerializer = null; Class<?> prevValueClass = null; final HashSet<String> ignored = _ignoredEntries; final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL_MAP_VALUES); for (Map.Entry<?,?> entry : value.entrySet()) { Object valueElem = entry.getValue(); // First, serialize key Object keyElem = entry.getKey(); if (keyElem == null) { provider.findNullKeySerializer(_keyType, _property).serialize(null, jgen, provider); } else { // [JACKSON-314] also may need to skip entries with null values if (skipNulls && valueElem == null) continue; // One twist: is entry ignorable? If so, skip if (ignored != null && ignored.contains(keyElem)) continue; keySerializer.serialize(keyElem, jgen, provider); } // And then value if (valueElem == null) { provider.defaultSerializeNull(jgen); } else { Class<?> cc = valueElem.getClass(); JsonSerializer<Object> currSerializer; if (cc == prevValueClass) { currSerializer

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> = prevValueSerializer; } else { if (_valueType.hasGenericTypes()) { currSerializer = provider.findValueSerializer(provider.constructSpecializedType(_valueType, cc), _property); } else { currSerializer = provider.findValueSerializer(cc, _property); } prevValueSerializer = currSerializer; prevValueClass = cc; } try { currSerializer.serializeWithType(valueElem, jgen, provider, _valueTypeSerializer); } catch (Exception e) { // [JACKSON-55] Need to add reference information String keyDesc = ""+keyElem; wrapAndThrow(provider, e, value, keyDesc); } } } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { ObjectNode o = createSchemaNode("object", true); //(ryan) even though it's possible to statically determine the "value" type of the map, // there's no way to statically determine the keys, so the "Entries" can't be determined. return o; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonMapFormatVisitor v2 = (visitor == null) ? null : visitor.expectMapFormat(typeHint); if (v2 != null) { v2.keyFormat(_keySerializer, _keyType); JsonSerializer<?> valueSer = _valueSerializer; if (valueSer == null) { valueSer = _findAndAddDynamic(_dynamicValueSerializers, _valueType, visitor.getProvider()); } v2.valueFormat(valueSer, _valueType); } } /* /********************************************************** /* Internal helper methods /********************************************************** */ protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map, Class<?> type, SerializerProvider provider) throws JsonMappingException { PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property); // did we get a new map of serializers? If so, start using it if (map != result.map) { _dynamicValueSerializers = result.map; } return result.serializer; } protected final

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map, JavaType type, SerializerProvider provider) throws JsonMappingException { PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property); if (map != result.map) { _dynamicValueSerializers = result.map; } return result.serializer; } protected Map<?,?> _orderEntries(Map<?,?> input) { // minor optimization: may already be sorted? if (input instanceof SortedMap<?,?>) { return input; } return new TreeMap<Object,Object>(input); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.IOException; import java.lang.reflect.Type; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonStringFormatVisitor; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonValueFormat; @JacksonStdImpl public class SqlTimeSerializer extends StdScalarSerializer<java.sql.Time> { public SqlTimeSerializer() { super(java.sql.Time.class); } @Override public void serialize(java.sql.Time value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeString(value.toString()); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("string", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonStringFormatVisitor v2 = (visitor == null) ? null : visitor.expectStringFormat(typeHint); if (v2 != null) { v2.format(JsonValueFormat.DATE_TIME); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> single value array for single 'String' value but there was more than a single value in the array"); } return parsed; } String value = jp.getValueAsString(); if (value != null) { return value; } throw ctxt.mappingException(String.class, jp.getCurrentToken()); } /** * Helper method called to determine if we are seeing String value of * "null", and, further, that it should be coerced to null just like * null token. * * @since 2.3 */ protected boolean _hasTextualNull(String value) { return "null".equals(value); } protected final boolean _isNegInf(String text) { return "-Infinity".equals(text) || "-INF".equals(text); } protected final boolean _isPosInf(String text) { return "Infinity".equals(text) || "INF".equals(text); } protected final boolean _isNaN(String text) { return "NaN".equals(text); } /* /**************************************************** /* Helper methods for sub-classes, resolving dependencies /**************************************************** */ /** * Helper method used to locate deserializers for properties the * type this deserializer handles contains (usually for properties of * bean types) * * @param type Type of property to deserialize * @param property Actual property object (field, method, constuctor parameter) used * for passing deserialized values; provided so deserializer can be contextualized if necessary (since 1.7) */ protected JsonDeserializer<Object> findDeserializer(DeserializationContext ctxt, JavaType type, BeanProperty property) throws JsonMappingException { return ctxt.findContextualValueDeserializer(type, property); } /* /********************************************************** /* Helper methods for sub-classes, deserializer construction /********************************************************** */ /** * Helper method that can be used to see if specified property has annotation * indicating that a converter is to be used for contained values (contents * of structured types; array/List/Map values) * * @param existingDeserializer (optional) configured content * serializer if one already exists. * * @since 2.2 */ protected JsonDeserializer<?> findConvertingContentDeserializer(DeserializationContext ctxt,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> BeanProperty prop, JsonDeserializer<?> existingDeserializer) throws JsonMappingException { final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); if (intr != null && prop != null) { Object convDef = intr.findDeserializationContentConverter(prop.getMember()); if (convDef != null) { Converter<Object,Object> conv = ctxt.converterInstance(prop.getMember(), convDef); JavaType delegateType = conv.getInputType(ctxt.getTypeFactory()); if (existingDeserializer == null) { existingDeserializer = ctxt.findContextualValueDeserializer(delegateType, prop); } return new StdDelegatingDeserializer<Object>(conv, delegateType, existingDeserializer); } } return existingDeserializer; } /* /********************************************************** /* Helper methods for sub-classes, problem reporting /********************************************************** */ /** * Method called to deal with a property that did not map to a known * Bean property. Method can deal with the problem as it sees fit (ignore, * throw exception); but if it does return, it has to skip the matching * Json content parser has. *<p> * NOTE: method signature was changed in version 1.5; explicit JsonParser * <b>must</b> be passed since it may be something other than what * context has. Prior versions did not include the first parameter. * * @param jp Parser that points to value of the unknown property * @param ctxt Context for deserialization; allows access to the parser, * error reporting functionality * @param instanceOrClass Instance that is being populated by this * deserializer, or if not known, Class that would be instantiated. * If null, will assume type is what {@link #getValueClass} returns. * @param propName Name of the property that can not be mapped */ protected void handleUnknownProperty(JsonParser jp, DeserializationContext ctxt, Object instanceOrClass, String propName) throws IOException { if (instanceOrClass == null) { instanceOrClass = handledType(); } // Maybe we have configured handler(s) to take care of it? if (ctxt.handleUnknownProperty(jp, this, instanceOrClass, propName)) { return; } // Nope, not handled

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Instantiator = valueInstantiator; _delegateDeserializer = (JsonDeserializer<Object>) delegateDeser; } protected StringCollectionDeserializer withResolved(JsonDeserializer<?> delegateDeser, JsonDeserializer<?> valueDeser) { if ((_valueDeserializer == valueDeser) && (_delegateDeserializer == delegateDeser)) { return this; } return new StringCollectionDeserializer(_collectionType, _valueInstantiator, delegateDeser, valueDeser); } /* /********************************************************** /* Validation, post-processing /********************************************************** */ @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { // May need to resolve types for delegate-based creators: JsonDeserializer<Object> delegate = null; if (_valueInstantiator != null) { AnnotatedWithParams delegateCreator = _valueInstantiator.getDelegateCreator(); if (delegateCreator != null) { JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig()); delegate = findDeserializer(ctxt, delegateType, property); } } JsonDeserializer<?> valueDeser = _valueDeserializer; if (valueDeser == null) { // #125: May have a content converter valueDeser = findConvertingContentDeserializer(ctxt, property, valueDeser); if (valueDeser == null) { // And we may also need to get deserializer for String valueDeser = ctxt.findContextualValueDeserializer( _collectionType.getContentType(), property); } } else { // if directly assigned, probably not yet contextual, so: valueDeser = ctxt.handleSecondaryContextualization(valueDeser, property); } if (isDefaultDeserializer(valueDeser)) { valueDeser = null; } return withResolved(delegate, valueDeser); } /* /********************************************************** /* ContainerDeserializerBase API /********************************************************** */ @Override public JavaType getContentType() { return _collectionType.getContentType(); } @SuppressWarnings("unchecked") @Override public JsonDeserializer<Object> getContentDeserializer() { JsonDeserializer<?> deser = _valueDeserializer; return (JsonDeserializer<Object>) deser; } /* /********************************************************** /* JsonDeserializer API

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> /********************************************************** */ @SuppressWarnings("unchecked") @Override public Collection<String> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { if (_delegateDeserializer != null) { return (Collection<String>) _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); } final Collection<String> result = (Collection<String>) _valueInstantiator.createUsingDefault(ctxt); return deserialize(jp, ctxt, result); } @Override public Collection<String> deserialize(JsonParser jp, DeserializationContext ctxt, Collection<String> result) throws IOException { // Ok: must point to START_ARRAY if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt, result); } if (_valueDeserializer != null) { return deserializeUsingCustom(jp, ctxt, result, _valueDeserializer); } JsonToken t; try { while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; } else { value = _parseString(jp, ctxt); } result.add(value); } } catch (Exception e) { // note: pass String.class, not String[].class, as we need element type for error info throw JsonMappingException.wrapWithPath(e, String.class, result.size()); } return result; } private Collection<String> deserializeUsingCustom(JsonParser jp, DeserializationContext ctxt, Collection<String> result, final JsonDeserializer<String> deser) throws IOException { JsonToken t; while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { String value; if (t == JsonToken.VALUE_NULL) { value = deser.getNullValue(); } else { value = deser.deserialize(jp, ctxt); } result.add(value); } return result; } @Override public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException { // In future

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.exc; import java.util.*; import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonMappingException; /** * Specialized {@link JsonMappingException} sub-class used to indicate * case where an explicitly ignored property is encountered, and mapper * is configured to consider this an error. * * @since 2.3 */ public class IgnoredPropertyException extends PropertyBindingException { private static final long serialVersionUID = 1L; public IgnoredPropertyException(String msg, JsonLocation loc, Class<?> referringClass, String propName, Collection<Object> propertyIds) { super(msg, loc, referringClass, propName, propertyIds); } /** * Factory method used for constructing instances of this exception type. * * @param jp Underlying parser used for reading input being used for data-binding * @param fromObjectOrClass Reference to either instance of problematic type ( * if available), or if not, type itself * @param propertyName Name of unrecognized property * @param propertyIds (optional, null if not available) Set of properties that * type would recognize, if completely known: null if set can not be determined. */ public static IgnoredPropertyException from(JsonParser jp, Object fromObjectOrClass, String propertyName, Collection<Object> propertyIds) { if (fromObjectOrClass == null) { throw new IllegalArgumentException(); } Class<?> ref; if (fromObjectOrClass instanceof Class<?>) { ref = (Class<?>) fromObjectOrClass; } else { ref = fromObjectOrClass.getClass(); } String msg = "Ignored field \""+propertyName+"\" (class "+ref.getName() +") encountered; mapper configured not to allow this"; IgnoredPropertyException e = new IgnoredPropertyException(msg, jp.getCurrentLocation(), ref, propertyName, propertyIds); // but let's also ensure path includes this last (missing) segment e.prependPath(fromObjectOrClass, propertyName); return e; } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.lang.reflect.Type; import java.io.IOException; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; /** * This is a simple dummy serializer that will just output literal * JSON null value whenever serialization is requested. * Used as the default "null serializer" (which is used for serializing * null object references unless overridden), as well as for some * more exotic types (java.lang.Void). */ @JacksonStdImpl public class NullSerializer extends StdSerializer<Object> { public final static NullSerializer instance = new NullSerializer(); private NullSerializer() { super(Object.class); } @Override public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeNull(); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { return createSchemaNode("null"); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { visitor.expectNullFormat(typeHint); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>length; BeanPropertyWriter[] result = new BeanPropertyWriter[len]; for (int i = 0; i < len; ++i) { BeanPropertyWriter bpw = props[i]; if (bpw != null) { result[i] = bpw.rename(transformer); } } return result; } /* /********************************************************** /* Post-constriction processing: resolvable, contextual /********************************************************** */ /** * We need to implement {@link ResolvableSerializer} to be able to * properly handle cyclic type references. */ @Override public void resolve(SerializerProvider provider) throws JsonMappingException { int filteredCount = (_filteredProps == null) ? 0 : _filteredProps.length; for (int i = 0, len = _props.length; i < len; ++i) { BeanPropertyWriter prop = _props[i]; // let's start with null serializer resolution actually if (!prop.willSuppressNulls() && !prop.hasNullSerializer()) { JsonSerializer<Object> nullSer = provider.findNullValueSerializer(prop); if (nullSer != null) { prop.assignNullSerializer(nullSer); // also: remember to replace filtered property too? (see [JACKSON-364]) if (i < filteredCount) { BeanPropertyWriter w2 = _filteredProps[i]; if (w2 != null) { w2.assignNullSerializer(nullSer); } } } } if (prop.hasSerializer()) { continue; } // [Issue#124]: allow use of converters JsonSerializer<Object> ser = findConvertingSerializer(provider, prop); if (ser == null) { // Was the serialization type hard-coded? If so, use it JavaType type = prop.getSerializationType(); // It not, we can use declared return type if and only if declared type is final: // if not, we don't really know the actual type until we get the instance. if (type == null) { type = provider.constructType(prop.getGenericPropertyType()); if (!type.isFinal()) { if (type.isContainerType() || type.containedTypeCount() > 0)

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> { prop.setNonTrivialBaseType(type); } continue; } } ser = provider.findValueSerializer(type, prop); /* 04-Feb-2010, tatu: We may have stashed type serializer for content types * too, earlier; if so, it's time to connect the dots here: */ if (type.isContainerType()) { TypeSerializer typeSer = type.getContentType().getTypeHandler(); if (typeSer != null) { // for now, can do this only for standard containers... if (ser instanceof ContainerSerializer<?>) { // ugly casts... but necessary @SuppressWarnings("unchecked") JsonSerializer<Object> ser2 = (JsonSerializer<Object>)((ContainerSerializer<?>) ser).withValueTypeSerializer(typeSer); ser = ser2; } } } } prop.assignSerializer(ser); // and maybe replace filtered property too? (see [JACKSON-364]) if (i < filteredCount) { BeanPropertyWriter w2 = _filteredProps[i]; if (w2 != null) { w2.assignSerializer(ser); } } } // also, any-getter may need to be resolved if (_anyGetterWriter != null) { _anyGetterWriter.resolve(provider); } } /** * Helper method that can be used to see if specified property is annotated * to indicate use of a converter for property value (in case of container types, * it is container type itself, not key or content type). * * @since 2.2 */ protected JsonSerializer<Object> findConvertingSerializer(SerializerProvider provider, BeanPropertyWriter prop) throws JsonMappingException { final AnnotationIntrospector intr = provider.getAnnotationIntrospector(); if (intr != null) { Object convDef = intr.findSerializationConverter(prop.getMember()); if (convDef != null) { Converter<Object,Object> conv = provider.converterInstance(prop.getMember(), convDef); JavaType delegateType = conv.getOutputType(provider.getTypeFactory()); JsonSerializer<?> ser = provider.findValueSerializer(delegateType, prop); return new StdDelegatingSerializer(conv, delegateType, ser);

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } } return null; } @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { ObjectIdWriter oiw = _objectIdWriter; String[] ignorals = null; Object newFilterId = null; final AnnotationIntrospector intr = provider.getAnnotationIntrospector(); final AnnotatedMember accessor = (property == null || intr == null) ? null : property.getMember(); // First: may have an override for Object Id: if (accessor != null) { ignorals = intr.findPropertiesToIgnore(accessor); ObjectIdInfo objectIdInfo = intr.findObjectIdInfo(accessor); if (objectIdInfo == null) { // no ObjectId override, but maybe ObjectIdRef? if (oiw != null) { objectIdInfo = intr.findObjectReferenceInfo(accessor, new ObjectIdInfo(NAME_FOR_OBJECT_REF, null, null, null)); oiw = _objectIdWriter.withAlwaysAsId(objectIdInfo.getAlwaysAsId()); } } else { /* Ugh: mostly copied from BeanSerializerBase: but can't easily * change it to be able to move to SerializerProvider (where it * really belongs) */ // 2.1: allow modifications by "id ref" annotations as well: objectIdInfo = intr.findObjectReferenceInfo(accessor, objectIdInfo); ObjectIdGenerator<?> gen; Class<?> implClass = objectIdInfo.getGeneratorType(); JavaType type = provider.constructType(implClass); JavaType idType = provider.getTypeFactory().findTypeParameters(type, ObjectIdGenerator.class)[0]; // Property-based generator is trickier if (implClass == ObjectIdGenerators.PropertyGenerator.class) { // most special one, needs extra work String propName = objectIdInfo.getPropertyName().getSimpleName(); BeanPropertyWriter idProp = null; for (int i = 0, len = _props.length ;; ++i) { if (i == len) { throw new IllegalArgumentException("Invalid Object Id definition for "+_handledType.getName() +": can not find property with name '"+propName+"'"); } BeanPropertyWriter prop = _props[i]; if (propName.equals(prop

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> (typeStr == null) { typeSer.writeTypeSuffixForObject(bean, jgen); } else { typeSer.writeCustomTypeSuffixForObject(bean, jgen, typeStr); } } private final String _customTypeId(Object bean) { final Object typeId = _typeId.getValue(bean); if (typeId == null) { return ""; } return (typeId instanceof String) ? (String) typeId : typeId.toString(); } /* /********************************************************** /* Field serialization methods /********************************************************** */ protected void serializeFields(Object bean, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { final BeanPropertyWriter[] props; if (_filteredProps != null && provider.getActiveView() != null) { props = _filteredProps; } else { props = _props; } int i = 0; try { for (final int len = props.length; i < len; ++i) { BeanPropertyWriter prop = props[i]; if (prop != null) { // can have nulls in filtered list prop.serializeAsField(bean, jgen, provider); } } if (_anyGetterWriter != null) { _anyGetterWriter.getAndSerialize(bean, jgen, provider); } } catch (Exception e) { String name = (i == props.length) ? "[anySetter]" : props[i].getName(); wrapAndThrow(provider, e, bean, name); } catch (StackOverflowError e) { /* 04-Sep-2009, tatu: Dealing with this is tricky, since we do not * have many stack frames to spare... just one or two; can't * make many calls. */ JsonMappingException mapE = new JsonMappingException("Infinite recursion (StackOverflowError)", e); String name = (i == props.length) ? "[anySetter]" : props[i].getName(); mapE.prependPath(new JsonMappingException.Reference(bean, name)); throw mapE; } } /** * Alternative serialization method that gets called when there is a * {@link PropertyFilter} that needs to be called to

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> determine * which properties are to be serialized (and possibly how) */ protected void serializeFieldsFiltered(Object bean, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { /* note: almost verbatim copy of "serializeFields"; copied (instead of merged) * so that old method need not add check for existence of filter. */ final BeanPropertyWriter[] props; if (_filteredProps != null && provider.getActiveView() != null) { props = _filteredProps; } else { props = _props; } final PropertyFilter filter = findPropertyFilter(provider, _propertyFilterId, bean); // better also allow missing filter actually.. if (filter == null) { serializeFields(bean, jgen, provider); return; } int i = 0; try { for (final int len = props.length; i < len; ++i) { BeanPropertyWriter prop = props[i]; if (prop != null) { // can have nulls in filtered list filter.serializeAsField(bean, jgen, provider, prop); } } if (_anyGetterWriter != null) { _anyGetterWriter.getAndFilter(bean, jgen, provider, filter); } } catch (Exception e) { String name = (i == props.length) ? "[anySetter]" : props[i].getName(); wrapAndThrow(provider, e, bean, name); } catch (StackOverflowError e) { JsonMappingException mapE = new JsonMappingException("Infinite recursion (StackOverflowError)", e); String name = (i == props.length) ? "[anySetter]" : props[i].getName(); mapE.prependPath(new JsonMappingException.Reference(bean, name)); throw mapE; } } @Deprecated @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { ObjectNode o = createSchemaNode("object", true); // [JACKSON-813]: Add optional JSON Schema id attribute, if found // NOTE: not optimal, does NOT go through AnnotationIntrospector etc: JsonSerializableSchema ann = _handledType.getAnnotation(JsonSerializableSchema.class); if (ann != null

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>) { String id = ann.id(); if (id != null && id.length() > 0) { o.put("id", id); } } //todo: should the classname go in the title? //o.put("title", _className); ObjectNode propertiesNode = o.objectNode(); final PropertyFilter filter; if (_propertyFilterId != null) { filter = findPropertyFilter(provider, _propertyFilterId, null); } else { filter = null; } for (int i = 0; i < _props.length; i++) { BeanPropertyWriter prop = _props[i]; if (filter == null) { prop.depositSchemaProperty(propertiesNode, provider); } else { filter.depositSchemaProperty(prop, propertiesNode, provider); } } o.put("properties", propertiesNode); return o; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { //deposit your output format if (visitor == null) { return; } JsonObjectFormatVisitor objectVisitor = visitor.expectObjectFormat(typeHint); if (objectVisitor == null) { return; } if (_propertyFilterId != null) { PropertyFilter filter = findPropertyFilter(visitor.getProvider(), _propertyFilterId, null); for (int i = 0; i < _props.length; i++) { filter.depositSchemaProperty(_props[i], objectVisitor, visitor.getProvider()); } } else { for (int i = 0; i < _props.length; i++) { _props[i].depositSchemaProperty(objectVisitor); } } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> = new LinkedHashMap<Object,Object>(); for (int i = 0, len = args.length; i < len; i += 2) { map.put(args[i], args[i+1]); } return m.writeValueAsString(map); } /* /********************************************************** /* Helper methods, deserialization /********************************************************** */ protected <T> T readAndMapFromString(String input, Class<T> cls) throws IOException { return readAndMapFromString(SHARED_MAPPER, input, cls); } protected <T> T readAndMapFromString(ObjectMapper m, String input, Class<T> cls) throws IOException { return (T) m.readValue("\""+input+"\"", cls); } /* /********************************************************** /* Helper methods, other /********************************************************** */ protected TimeZone getUTCTimeZone() { return TimeZone.getTimeZone("GMT"); } protected byte[] utf8Bytes(String str) { try { return str.getBytes("UTF-8"); } catch (IOException e) { throw new IllegalArgumentException(e); } } protected String aposToQuotes(String json) { return json.replace("'", "\""); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.impl; import java.io.IOException; import java.lang.reflect.Type; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.ser.std.StdSerializer; /** * Special bogus "serializer" that will throw * {@link JsonGenerationException} if its {@link #serialize} * gets invoked. Most commonly registered as handler for unknown types, * as well as for catching unintended usage (like trying to use null * as Map/Object key). */ public final class FailingSerializer extends StdSerializer<Object> { final String _msg; public FailingSerializer(String msg) { super(Object.class); _msg = msg; } @Override public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { throw new JsonGenerationException(_msg); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { return null; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) { ; } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser; import java.io.IOException; import java.util.*; import java.util.concurrent.ArrayBlockingQueue; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; @SuppressWarnings("serial") public class TestCollectionDeserialization extends BaseMapTest { enum Key { KEY1, KEY2, WHATEVER; } @JsonDeserialize(using=ListDeserializer.class) static class CustomList extends LinkedList<String> { } static class ListDeserializer extends StdDeserializer<CustomList> { public ListDeserializer() { super(CustomList.class); } @Override public CustomList deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { CustomList result = new CustomList(); result.add(jp.getText()); return result; } } static class XBean { public int x; } // [Issue#199] static class ListAsIterable { public Iterable<String> values; } static class ListAsIterableX { public Iterable<XBean> nums; } static class KeyListBean { public List<Key> keys; } /* /********************************************************** /* Test methods /********************************************************** */ private final static ObjectMapper MAPPER = new ObjectMapper(); public void testUntypedList() throws Exception { // to get "untyped" default List, pass Object.class String JSON = "[ \"text!\", true, null, 23 ]"; // Not a guaranteed cast theoretically, but will work: // (since we know that Jackson will construct an ArrayList here...) Object value = MAPPER.readValue(JSON, Object.class); assertNotNull(value); assertTrue(value instanceof ArrayList<?>); List<?> result = (List<?>) value; assertEquals(4, result.size()); assertEquals("text!", result.get(0)); assertEquals(Boolean.TRUE, result.get(1)); assertNull(result.get(2)); assertEquals(Integer.valueOf(23), result

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>.get(3)); } public void testExactStringCollection() throws Exception { // to get typing, must use type reference String JSON = "[ \"a\", \"b\" ]"; List<String> result = MAPPER.readValue(JSON, new TypeReference<ArrayList<String>>() { }); assertNotNull(result); assertEquals(ArrayList.class, result.getClass()); assertEquals(2, result.size()); assertEquals("a", result.get(0)); assertEquals("b", result.get(1)); } public void testHashSet() throws Exception { String JSON = "[ \"KEY1\", \"KEY2\" ]"; EnumSet<Key> result = MAPPER.readValue(JSON, new TypeReference<EnumSet<Key>>() { }); assertNotNull(result); assertTrue(EnumSet.class.isAssignableFrom(result.getClass())); assertEquals(2, result.size()); assertTrue(result.contains(Key.KEY1)); assertTrue(result.contains(Key.KEY2)); assertFalse(result.contains(Key.WHATEVER)); } /// Test to verify that @JsonDeserialize.using works as expected public void testCustomDeserializer() throws IOException { CustomList result = MAPPER.readValue(quote("abc"), CustomList.class); assertEquals(1, result.size()); assertEquals("abc", result.get(0)); } // Testing [JACKSON-526], "implicit JSON array" for single-element arrays, // mostly produced by Jettison, Badgerfish conversions (from XML) @SuppressWarnings("unchecked") public void testImplicitArrays() throws Exception { // can't share mapper, custom configs (could create ObjectWriter tho) ObjectMapper mapper = new ObjectMapper(); mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); // first with simple scalar types (numbers), with collections List<Integer> ints = mapper.readValue("4", List.class); assertEquals(1, ints.size()); assertEquals(Integer.valueOf(4), ints.get(0)); List<String> strings = mapper.readValue(quote("abc"), new TypeReference<ArrayList<String>>() { }); assertEquals(1, strings.size()); assertEquals("abc", strings.get(0)); // and arrays: int[] intArray = mapper

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>.readValue("-7", int[].class); assertEquals(1, intArray.length); assertEquals(-7, intArray[0]); String[] stringArray = mapper.readValue(quote("xyz"), String[].class); assertEquals(1, stringArray.length); assertEquals("xyz", stringArray[0]); // and then with Beans: List<XBean> xbeanList = mapper.readValue("{\"x\":4}", new TypeReference<List<XBean>>() { }); assertEquals(1, xbeanList.size()); assertEquals(XBean.class, xbeanList.get(0).getClass()); Object ob = mapper.readValue("{\"x\":29}", XBean[].class); XBean[] xbeanArray = (XBean[]) ob; assertEquals(1, xbeanArray.length); assertEquals(XBean.class, xbeanArray[0].getClass()); } // [JACKSON-620]: allow "" to mean 'null' for Maps public void testFromEmptyString() throws Exception { ObjectReader r = MAPPER.reader(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT); List<?> result = r.withType(List.class).readValue(quote("")); assertNull(result); } // [Issue#161] public void testArrayBlockingQueue() throws Exception { // ok to skip polymorphic type to get Object ArrayBlockingQueue<?> q = MAPPER.readValue("[1, 2, 3]", ArrayBlockingQueue.class); assertNotNull(q); assertEquals(3, q.size()); assertEquals(Integer.valueOf(1), q.take()); assertEquals(Integer.valueOf(2), q.take()); assertEquals(Integer.valueOf(3), q.take()); } // [Issue#199] public void testIterableWithStrings() throws Exception { String JSON = "{ \"values\":[\"a\",\"b\"]}"; ListAsIterable w = MAPPER.readValue(JSON, ListAsIterable.class); assertNotNull(w); assertNotNull(w.values); Iterator<String> it = w.values.iterator(); assertTrue(it.hasNext()); assertEquals("a", it.next()); assertEquals("b", it.next()); assertFalse(it.hasNext()); } public void testIterableWithBeans() throws Exception { String

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> JSON = "{ \"nums\":[{\"x\":1},{\"x\":2}]}"; ListAsIterableX w = MAPPER.readValue(JSON, ListAsIterableX.class); assertNotNull(w); assertNotNull(w.nums); Iterator<XBean> it = w.nums.iterator(); assertTrue(it.hasNext()); XBean xb = it.next(); assertNotNull(xb); assertEquals(1, xb.x); xb = it.next(); assertEquals(2, xb.x); assertFalse(it.hasNext()); } // for [Issue#506] public void testArrayIndexForExceptions() throws Exception { final String OBJECTS_JSON = "[ \"KEY2\", false ]"; try { MAPPER.readValue(OBJECTS_JSON, Key[].class); fail("Should not pass"); } catch (JsonMappingException e) { verifyException(e, "Can not deserialize"); List<JsonMappingException.Reference> refs = e.getPath(); assertEquals(1, refs.size()); assertEquals(1, refs.get(0).getIndex()); } try { MAPPER.readValue("[ \"xyz\", { } ]", String[].class); fail("Should not pass"); } catch (JsonMappingException e) { verifyException(e, "Can not deserialize"); List<JsonMappingException.Reference> refs = e.getPath(); assertEquals(1, refs.size()); assertEquals(1, refs.get(0).getIndex()); } try { MAPPER.readValue("{\"keys\":"+OBJECTS_JSON+"}", KeyListBean.class); fail("Should not pass"); } catch (JsonMappingException e) { verifyException(e, "Can not deserialize"); List<JsonMappingException.Reference> refs = e.getPath(); assertEquals(2, refs.size()); // Bean has no index, but has name: assertEquals(-1, refs.get(0).getIndex()); assertEquals("keys", refs.get(0).getFieldName()); // and for List, reverse: assertEquals(1, refs.get(1).getIndex()); assertNull(refs.get(1).getFieldName()); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> associated schema. * * @since 2.2 */ public boolean isRequired(); /** * Method for finding annotation associated with this property; * meaning annotation associated with one of entities used to * access property. */ public <A extends Annotation> A getAnnotation(Class<A> acls); /** * Method for finding annotation associated with context of * this property; usually class in which member is declared * (or its subtype if processing subtype). */ public <A extends Annotation> A getContextAnnotation(Class<A> acls); /** * Method for accessing primary physical entity that represents the property; * annotated field, method or constructor property. */ public AnnotatedMember getMember(); /** * Method that can be called to visit the type structure that this * property is part of. * Note that not all implementations support traversal with this * method; those that do not should throw * {@link UnsupportedOperationException}. * * @param objectVisitor Visitor to used as the callback handler * * @since 2.2 */ public void depositSchemaProperty(JsonObjectFormatVisitor objectVisitor) throws JsonMappingException; /* /********************************************************** /* Helper classes /********************************************************** */ /** * Simple stand-alone implementation, useful as a placeholder * or base class for more complex implementations. */ public static class Std implements BeanProperty { protected final PropertyName _name; protected final JavaType _type; protected final PropertyName _wrapperName; protected final PropertyMetadata _metadata; /** * Physical entity (field, method or constructor argument) that * is used to access value of property (or in case of constructor * property, just placeholder) */ protected final AnnotatedMember _member; /** * Annotations defined in the context class (if any); may be null * if no annotations were found */ protected final Annotations _contextAnnotations; public Std(PropertyName name, JavaType type, PropertyName wrapperName, Annotations contextAnnotations, AnnotatedMember member, PropertyMetadata metadata) { _name = name; _type = type; _wrapperName = wrapperName; _metadata = metadata; _member = member; _contextAnnotations = contextAnnotations; } @Deprecated // since 2.3

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> no view has been set. */ public abstract Class<?> getActiveView(); /* /********************************************************** /* Generic attributes (2.3+) /********************************************************** */ /** * Method for accessing attributes available in this context. * Per-call attributes have highest precedence; attributes set * via {@link ObjectReader} or {@link ObjectWriter} have lower * precedence. * * @param key Key of the attribute to get * @return Value of the attribute, if any; null otherwise * * @since 2.3 */ public abstract Object getAttribute(Object key); /** * Method for setting per-call value of given attribute. * This will override any previously defined value for the * attribute within this context. * * @param key Key of the attribute to set * @param value Value to set attribute to * * @return This context object, to allow chaining * * @since 2.3 */ public abstract DatabindContext setAttribute(Object key, Object value); /* /********************************************************** /* Type instantiation/resolution /********************************************************** */ /** * Convenience method for constructing {@link JavaType} for given JDK * type (usually {@link java.lang.Class}) */ public JavaType constructType(Type type) { return getTypeFactory().constructType(type); } /** * Convenience method for constructing subtypes, retaining generic * type parameter (if any) */ public JavaType constructSpecializedType(JavaType baseType, Class<?> subclass) { // simple optimization to avoid costly introspection if type-erased type does NOT differ if (baseType.getRawClass() == subclass) { return baseType; } return getConfig().constructSpecializedType(baseType, subclass); } public abstract TypeFactory getTypeFactory(); /* /********************************************************** /* Helper object construction /********************************************************** */ public ObjectIdGenerator<?> objectIdGeneratorInstance(Annotated annotated, ObjectIdInfo objectIdInfo) throws JsonMappingException { Class<?> implClass = objectIdInfo.getGeneratorType(); final MapperConfig<?> config = getConfig(); HandlerInstantiator hi = config.getHandlerInstantiator(); ObjectIdGenerator<?> gen = (hi == null) ? null : hi.objectIdGeneratorInstance(config,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> annotated, implClass); if (gen == null) { gen = (ObjectIdGenerator<?>) ClassUtil.createInstance(implClass, config.canOverrideAccessModifiers()); } return gen.forScope(objectIdInfo.getScope()); } public ObjectIdResolver objectIdResolverInstance(Annotated annotated, ObjectIdInfo objectIdInfo) { Class<? extends ObjectIdResolver> implClass = objectIdInfo.getResolverType(); final MapperConfig<?> config = getConfig(); HandlerInstantiator hi = config.getHandlerInstantiator(); ObjectIdResolver resolver = (hi == null) ? null : hi.resolverIdGeneratorInstance(config, annotated, implClass); if (resolver == null) { resolver = ClassUtil.createInstance(implClass, config.canOverrideAccessModifiers()); } return resolver; } /** * Helper method to use to construct a {@link Converter}, given a definition * that may be either actual converter instance, or Class for instantiating one. * * @since 2.2 */ @SuppressWarnings("unchecked") public Converter<Object,Object> converterInstance(Annotated annotated, Object converterDef) throws JsonMappingException { if (converterDef == null) { return null; } if (converterDef instanceof Converter<?,?>) { return (Converter<Object,Object>) converterDef; } if (!(converterDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned Converter definition of type " +converterDef.getClass().getName()+"; expected type Converter or Class<Converter> instead"); } Class<?> converterClass = (Class<?>)converterDef; // there are some known "no class" markers to consider too: if (converterClass == Converter.None.class || ClassUtil.isBogusClass(converterClass)) { return null; } if (!Converter.class.isAssignableFrom(converterClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class " +converterClass.getName()+"; expected Class<Converter>"); } final MapperConfig<?> config = getConfig(); HandlerInstantiator hi = config.getHandlerInstantiator(); Converter<?,?> conv = (hi == null) ? null : hi.converterInstance(config, annotated, converterClass); if (conv == null) { conv = (Converter<?,?>) ClassUtil.create

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> not need JSON * Array or Object start/end markers), and then write type suffix. * This should work for most cases; some sub-classes may want to * change this behavior. */ @Override public void serializeWithType(Object value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonGenerationException { typeSer.writeTypePrefixForScalar(value, jgen); serialize(value, jgen, provider); typeSer.writeTypeSuffixForScalar(value, jgen); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { return createSchemaNode("string", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { if (visitor != null) { visitor.expectStringFormat(typeHint); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> jp, DeserializationContext ctxt, Object instance) throws IOException, JsonProcessingException { deserializeSetAndReturn(jp, ctxt, instance); } @Override public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException, JsonProcessingException { boolean usingIdentityInfo = _objectIdInfo != null || _valueDeserializer.getObjectIdReader() != null; try { return setAndReturn(instance, deserialize(jp, ctxt)); } catch (UnresolvedForwardReference reference) { if (!usingIdentityInfo) { throw JsonMappingException.from(jp, "Unresolved forward reference but no identity info.", reference); } reference.getRoid().appendReferring(new PropertyReferring(this, reference, _type.getRawClass(), instance)); return null; } } @Override public void set(Object instance, Object value) throws IOException { _forward.set(instance, value); } @Override public Object setAndReturn(Object instance, Object value) throws IOException { return _forward.setAndReturn(instance, value); } public final static class PropertyReferring extends Referring { private final ObjectIdReferenceProperty _parent; public final Object _pojo; public PropertyReferring(ObjectIdReferenceProperty parent, UnresolvedForwardReference ref, Class<?> type, Object ob) { super(ref, type); _parent = parent; _pojo = ob; } @Override public void handleResolvedForwardReference(Object id, Object value) throws IOException { if (!hasId(id)) { throw new IllegalArgumentException("Trying to resolve a forward reference with id [" + id + "] that wasn't previously seen as unresolved."); } _parent.set(_pojo, value); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> null); _elementType = elemType; _staticTyping = staticTyping; _valueTypeSerializer = vts; _dynamicSerializers = PropertySerializerMap.emptyMap(); _elementSerializer = elementSerializer; } public ObjectArraySerializer(ObjectArraySerializer src, TypeSerializer vts) { super(src); _elementType = src._elementType; _valueTypeSerializer = vts; _staticTyping = src._staticTyping; _dynamicSerializers = src._dynamicSerializers; _elementSerializer = src._elementSerializer; } @SuppressWarnings("unchecked") public ObjectArraySerializer(ObjectArraySerializer src, BeanProperty property, TypeSerializer vts, JsonSerializer<?> elementSerializer) { super(src, property); _elementType = src._elementType; _valueTypeSerializer = vts; _staticTyping = src._staticTyping; _dynamicSerializers = src._dynamicSerializers; _elementSerializer = (JsonSerializer<Object>) elementSerializer; } @Override public ContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts) { return new ObjectArraySerializer(_elementType, _staticTyping, vts, _elementSerializer); } public ObjectArraySerializer withResolved(BeanProperty prop, TypeSerializer vts, JsonSerializer<?> ser) { if (_property == prop && ser == _elementSerializer && _valueTypeSerializer == vts) { return this; } return new ObjectArraySerializer(this, prop, vts, ser); } /* /********************************************************** /* Post-processing /********************************************************** */ @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { TypeSerializer vts = _valueTypeSerializer; if (vts != null) { vts = vts.forProperty(property); } /* 29-Sep-2012, tatu: Actually, we need to do much more contextual * checking here since we finally know for sure the property, * and it may have overrides */ JsonSerializer<?> ser = null; // First: if we have a property, may have property-annotation overrides if (property != null) { AnnotatedMember m = property.getMember(); if (m != null) { Object serDef =

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> continue; } Class<?> cc = elem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { // To fix [JACKSON-508] if (_elementType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_elementType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } } serializer.serialize(elem, jgen, provider); } } catch (IOException ioe) { throw ioe; } catch (Exception e) { // [JACKSON-55] Need to add reference information /* 05-Mar-2009, tatu: But one nasty edge is when we get * StackOverflow: usually due to infinite loop. But that gets * hidden within an InvocationTargetException... */ Throwable t = e; while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } if (t instanceof Error) { throw (Error) t; } throw JsonMappingException.wrapWithPath(t, elem, i); } } public void serializeContentsUsing(Object[] value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException, JsonGenerationException { final int len = value.length; final TypeSerializer typeSer = _valueTypeSerializer; int i = 0; Object elem = null; try { for (; i < len; ++i) { elem = value[i]; if (elem == null) { provider.defaultSerializeNull(jgen); continue; } if (typeSer == null) { ser.serialize(elem, jgen, provider); } else { ser.serializeWithType(elem, jgen, provider, typeSer); } } } catch (IOException ioe) { throw ioe; } catch (Exception e) { Throwable t = e; while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } if (t instanceof Error) { throw (Error) t; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> throw JsonMappingException.wrapWithPath(t, elem, i); } } public void serializeTypedContents(Object[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { final int len = value.length; final TypeSerializer typeSer = _valueTypeSerializer; int i = 0; Object elem = null; try { PropertySerializerMap serializers = _dynamicSerializers; for (; i < len; ++i) { elem = value[i]; if (elem == null) { provider.defaultSerializeNull(jgen); continue; } Class<?> cc = elem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { serializer = _findAndAddDynamic(serializers, cc, provider); } serializer.serializeWithType(elem, jgen, provider, typeSer); } } catch (IOException ioe) { throw ioe; } catch (Exception e) { Throwable t = e; while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } if (t instanceof Error) { throw (Error) t; } throw JsonMappingException.wrapWithPath(t, elem, i); } } @SuppressWarnings("deprecation") @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { ObjectNode o = createSchemaNode("array", true); if (typeHint != null) { JavaType javaType = provider.constructType(typeHint); if (javaType.isArrayType()) { Class<?> componentType = ((ArrayType) javaType).getContentType().getRawClass(); // 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped? if (componentType == Object.class) { o.put("items", com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode()); } else { JsonSerializer<Object> ser = provider.findValueSerializer(componentType, _property); JsonNode schemaNode = (ser instanceof SchemaAware) ? ((SchemaAware) ser).getSchema(provider, null) :

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode(); o.put("items", schemaNode); } } } return o; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonArrayFormatVisitor arrayVisitor = visitor.expectArrayFormat(typeHint); if (arrayVisitor != null) { TypeFactory tf = visitor.getProvider().getTypeFactory(); JavaType contentType = tf.moreSpecificType(_elementType, typeHint.getContentType()); if (contentType == null) { throw new JsonMappingException("Could not resolve type"); } JsonSerializer<?> valueSer = _elementSerializer; if (valueSer == null) { valueSer = visitor.getProvider().findValueSerializer(contentType, _property); } arrayVisitor.itemsFormat(valueSer, contentType); } } protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map, Class<?> type, SerializerProvider provider) throws JsonMappingException { PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property); // did we get a new map of serializers? If so, start using it if (map != result.map) { _dynamicSerializers = result.map; } return result.serializer; } protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map, JavaType type, SerializerProvider provider) throws JsonMappingException { PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property); // did we get a new map of serializers? If so, start using it if (map != result.map) { _dynamicSerializers = result.map; } return result.serializer; } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Type; protected Base(Class<T> cls, JsonParser.NumberType numberType, String schemaType) { super(cls); _numberType = numberType; _schemaType = schemaType; } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode(_schemaType, true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint); if (v2 != null) { v2.numberType(_numberType); } } @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { if (property != null) { JsonFormat.Value format = prov.getAnnotationIntrospector().findFormat(property.getMember()); if (format != null) { switch (format.getShape()) { case STRING: return ToStringSerializer.instance; default: } } } return this; } } /* /********************************************************** /* Concrete serializers, numerics /********************************************************** */ @JacksonStdImpl public final static class ShortSerializer extends Base<Short> { final static ShortSerializer instance = new ShortSerializer(); public ShortSerializer() { super(Short.class, JsonParser.NumberType.INT, "number"); } @Override public void serialize(Short value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeNumber(value.shortValue()); } } /** * This is the special serializer for regular {@link java.lang.Integer}s * (and primitive ints) *<p> * Since this is one of "native" types, no type information is ever * included on serialization (unlike for most scalar types as of 1.5) */ @JacksonStdImpl public final static class IntegerSerializer extends Base<Integer> { public IntegerSerializer() { super(Integer.class, JsonParser.NumberType.INT ,"integer"); } @Override public void serialize(Integer value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeNumber(value.intValue());

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>, String encoding) throws IOException, JsonParseException { /* 23-Apr-2008, tatus: UTF-32 is not supported by JDK, have to * use our own codec too (which is not optimal since there's * a chance both encoder and decoder might have bugs, but ones * that cancel each other out or such) */ byte[] data; if (encoding.equalsIgnoreCase("UTF-32")) { data = encodeInUTF32BE(input); } else { data = input.getBytes(encoding); } InputStream is = new ByteArrayInputStream(data); return f.createParser(is); } /* /********************************************************** /* Additional assertion methods /********************************************************** */ protected void assertToken(JsonToken expToken, JsonToken actToken) { if (actToken != expToken) { fail("Expected token "+expToken+", current token "+actToken); } } protected void assertToken(JsonToken expToken, JsonParser jp) { assertToken(expToken, jp.getCurrentToken()); } protected void assertType(Object ob, Class<?> expType) { if (ob == null) { fail("Expected an object of type "+expType.getName()+", got null"); } Class<?> cls = ob.getClass(); if (!expType.isAssignableFrom(cls)) { fail("Expected type "+expType.getName()+", got "+cls.getName()); } } protected void assertValidLocation(JsonLocation location) { assertNotNull("Should have non-null location", location); assertTrue("Should have positive line number", location.getLineNr() > 0); } protected void verifyException(Throwable e, String... matches) { String msg = e.getMessage(); String lmsg = (msg == null) ? "" : msg.toLowerCase(); for (String match : matches) { String lmatch = match.toLowerCase(); if (lmsg.indexOf(lmatch) >= 0) { return; } } fail("Expected an exception with one of substrings ("+Arrays.asList(matches)+"): got one with message \""+msg+"\""); } /** * Method that gets textual contents of the current token using * available methods, and ensures results

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser.std; import java.io.IOException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonMappingException; public class StackTraceElementDeserializer extends StdScalarDeserializer<StackTraceElement> { private static final long serialVersionUID = 1L; public StackTraceElementDeserializer() { super(StackTraceElement.class); } @Override public StackTraceElement deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { JsonToken t = jp.getCurrentToken(); // Must get an Object if (t == JsonToken.START_OBJECT) { String className = "", methodName = "", fileName = ""; int lineNumber = -1; while ((t = jp.nextValue()) != JsonToken.END_OBJECT) { String propName = jp.getCurrentName(); if ("className".equals(propName)) { className = jp.getText(); } else if ("fileName".equals(propName)) { fileName = jp.getText(); } else if ("lineNumber".equals(propName)) { if (t.isNumeric()) { lineNumber = jp.getIntValue(); } else { throw JsonMappingException.from(jp, "Non-numeric token ("+t+") for property 'lineNumber'"); } } else if ("methodName".equals(propName)) { methodName = jp.getText(); } else if ("nativeMethod".equals(propName)) { // no setter, not passed via constructor: ignore } else { handleUnknownProperty(jp, ctxt, _valueClass, propName); } } return new StackTraceElement(className, methodName, fileName, lineNumber); } else if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { jp.nextToken(); final StackTraceElement value = deserialize(jp, ctxt); if (jp.nextToken() != JsonToken.END_ARRAY) { throw ctxt.wrongTokenException(jp, JsonToken.END_ARRAY, "Attempted to unwrap single value array for

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>** */ protected JsonDeserializer<Object> _mapDeserializer; protected JsonDeserializer<Object> _listDeserializer; protected JsonDeserializer<Object> _stringDeserializer; protected JsonDeserializer<Object> _numberDeserializer; public UntypedObjectDeserializer() { super(Object.class); } @SuppressWarnings("unchecked") public UntypedObjectDeserializer(UntypedObjectDeserializer base, JsonDeserializer<?> mapDeser, JsonDeserializer<?> listDeser, JsonDeserializer<?> stringDeser, JsonDeserializer<?> numberDeser) { super(Object.class); _mapDeserializer = (JsonDeserializer<Object>) mapDeser; _listDeserializer = (JsonDeserializer<Object>) listDeser; _stringDeserializer = (JsonDeserializer<Object>) stringDeser; _numberDeserializer = (JsonDeserializer<Object>) numberDeser; } /* /********************************************************** /* Initialization /********************************************************** */ /** * We need to implement this method to properly find things to delegate * to: it can not be done earlier since delegated deserializers almost * certainly require access to this instance (at least "List" and "Map" ones) */ @Override public void resolve(DeserializationContext ctxt) throws JsonMappingException { JavaType obType = ctxt.constructType(Object.class); JavaType stringType = ctxt.constructType(String.class); TypeFactory tf = ctxt.getTypeFactory(); _mapDeserializer = _findCustomDeser(ctxt, tf.constructMapType(Map.class, stringType, obType)); _listDeserializer = _findCustomDeser(ctxt, tf.constructCollectionType(List.class, obType)); _stringDeserializer = _findCustomDeser(ctxt, stringType); _numberDeserializer = _findCustomDeser(ctxt, tf.constructType(Number.class)); } @SuppressWarnings("unchecked") protected JsonDeserializer<Object> _findCustomDeser(DeserializationContext ctxt, JavaType type) throws JsonMappingException { // NOTE: since we don't yet have the referring property, this should be fine: JsonDeserializer<?> deser = ctxt.findRootValueDeserializer(type); if (ClassUtil.isJacksonStdImpl(deser)) { return null; } return (JsonDeserializer<Object>) deser; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { // 20-Apr-2014, tatu: If nothing custom, let's use "vanilla" instance, // simpler and can avoid some of delegation if ((_stringDeserializer == null) && (_numberDeserializer == null) && (_mapDeserializer == null) && (_listDeserializer == null) && getClass() == UntypedObjectDeserializer.class) { return Vanilla.std; } JsonDeserializer<?> mapDeserializer = _mapDeserializer; if (mapDeserializer instanceof ContextualDeserializer) { mapDeserializer = ((ContextualDeserializer)mapDeserializer).createContextual(ctxt, property); } JsonDeserializer<?> listDeserializer = _listDeserializer; if (listDeserializer instanceof ContextualDeserializer) { listDeserializer = ((ContextualDeserializer)listDeserializer).createContextual(ctxt, property); } JsonDeserializer<?> stringDeserializer = _stringDeserializer; if (stringDeserializer instanceof ContextualDeserializer) { stringDeserializer = ((ContextualDeserializer)stringDeserializer).createContextual(ctxt, property); } JsonDeserializer<?> numberDeserializer = _numberDeserializer; if (numberDeserializer instanceof ContextualDeserializer) { numberDeserializer = ((ContextualDeserializer)numberDeserializer).createContextual(ctxt, property); } // And if anything changed, we'll need to change too! if ((mapDeserializer != _mapDeserializer) || (listDeserializer != _listDeserializer) || (stringDeserializer != _stringDeserializer) || (numberDeserializer != _numberDeserializer) ) { return _withResolved(mapDeserializer, listDeserializer, stringDeserializer, numberDeserializer); } return this; } protected JsonDeserializer<?> _withResolved(JsonDeserializer<?> mapDeser, JsonDeserializer<?> listDeser, JsonDeserializer<?> stringDeser, JsonDeserializer<?> numberDeser) { return new UntypedObjectDeserializer(this, mapDeser, listDeser, stringDeser, numberDeser); } /* /********************************************************** /* Deserializer API /********************************************************** */ @Override public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { switch (jp.getCurrentToken()) { case FIELD_NAME: case START_OBJECT: if

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> if (f == null) { throw new IllegalArgumentException("No Field passed for property '"+src.getName() +"' (class "+src.getDeclaringClass().getName()+")"); } _field = f; } @Override public FieldProperty withName(PropertyName newName) { return new FieldProperty(this, newName); } @Override public FieldProperty withValueDeserializer(JsonDeserializer<?> deser) { return new FieldProperty(this, deser); } /* /********************************************************** /* BeanProperty impl /********************************************************** */ @Override public <A extends Annotation> A getAnnotation(Class<A> acls) { return _annotated.getAnnotation(acls); } @Override public AnnotatedMember getMember() { return _annotated; } /* /********************************************************** /* Overridden methods /********************************************************** */ @Override public void deserializeAndSet(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException, JsonProcessingException { set(instance, deserialize(jp, ctxt)); } @Override public Object deserializeSetAndReturn(JsonParser jp, DeserializationContext ctxt, Object instance) throws IOException, JsonProcessingException { return setAndReturn(instance, deserialize(jp, ctxt)); } @Override public final void set(Object instance, Object value) throws IOException { try { _field.set(instance, value); } catch (Exception e) { _throwAsIOE(e, value); } } @Override public Object setAndReturn(Object instance, Object value) throws IOException { try { _field.set(instance, value); } catch (Exception e) { _throwAsIOE(e, value); } return instance; } /* /********************************************************** /* JDK serialization handling /********************************************************** */ Object readResolve() { return new FieldProperty(this, _annotated.getAnnotated()); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.impl; import com.fasterxml.jackson.annotation.ObjectIdGenerator; import com.fasterxml.jackson.annotation.ObjectIdGenerators; import com.fasterxml.jackson.databind.introspect.ObjectIdInfo; import com.fasterxml.jackson.databind.ser.*; public class PropertyBasedObjectIdGenerator extends ObjectIdGenerators.PropertyGenerator { private static final long serialVersionUID = 1L; protected final BeanPropertyWriter _property; public PropertyBasedObjectIdGenerator(ObjectIdInfo oid, BeanPropertyWriter prop) { this(oid.getScope(), prop); } protected PropertyBasedObjectIdGenerator(Class<?> scope, BeanPropertyWriter prop) { super(scope); _property = prop; } /** * We must override this method, to prevent errors when scopes are the same, * but underlying class (on which to access property) is different. */ @Override public boolean canUseFor(ObjectIdGenerator<?> gen) { if (gen.getClass() == getClass()) { PropertyBasedObjectIdGenerator other = (PropertyBasedObjectIdGenerator) gen; if (other.getScope() == _scope) { /* 26-Jul-2012, tatu: This is actually not enough, because the property * accessor within BeanPropertyWriter won't work for other property fields * (see [https://github.com/FasterXML/jackson-module-jaxb-annotations/issues/9] * for details). * So we need to verify that underlying property is actually the same. */ return (other._property == _property); } } return false; } @Override public Object generateId(Object forPojo) { try { return _property.get(forPojo); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new IllegalStateException("Problem accessing property '" +_property.getName()+"': "+e.getMessage(), e); } } @Override public ObjectIdGenerator<Object> forScope(Class<?> scope) { return (scope == _scope) ? this : new PropertyBasedObjectIdGenerator(scope, _property); } @Override public ObjectIdGenerator<Object> newForSerialization(Object context) { // No state

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> * we'll ignore it... */ @Override public ContainerSerializer<?> _withValueTypeSerializer(TypeSerializer vts) { return this; } /* /********************************************************** /* Post-processing /********************************************************** */ @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { /* 29-Sep-2012, tatu: Actually, we need to do much more contextual * checking here since we finally know for sure the property, * and it may have overrides */ JsonSerializer<?> ser = null; // First: if we have a property, may have property-annotation overrides if (property != null) { AnnotatedMember m = property.getMember(); if (m != null) { Object serDef = provider.getAnnotationIntrospector().findContentSerializer(m); if (serDef != null) { ser = provider.serializerInstance(m, serDef); } } } if (ser == null) { ser = _elementSerializer; } // #124: May have a content converter ser = findConvertingContentSerializer(provider, property, ser); if (ser == null) { ser = provider.findValueSerializer(String.class, property); } else { ser = provider.handleSecondaryContextualization(ser, property); } // Optimization: default serializer just writes String, so we can avoid a call: if (isDefaultSerializer(ser)) { ser = null; } // note: will never have TypeSerializer, because Strings are "natural" type if (ser == _elementSerializer) { return this; } return new StringArraySerializer(this, property, ser); } /* /********************************************************** /* Simple accessors /********************************************************** */ @Override public JavaType getContentType() { return VALUE_TYPE; } @Override public JsonSerializer<?> getContentSerializer() { return _elementSerializer; } @Override public boolean isEmpty(String[] value) { return (value == null) || (value.length == 0); } @Override public boolean hasSingleElement(String[] value) { return (value.length == 1); } /* /

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>********************************************************** /* Actual serialization /********************************************************** */ @Override public void serializeContents(String[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { final int len = value.length; if (len == 0) { return; } if (_elementSerializer != null) { serializeContentsSlow(value, jgen, provider, _elementSerializer); return; } /* 08-Dec-2008, tatus: If we want this to be fully overridable * (for example, to support String cleanup during writing * or something), we should find serializer by provider. * But for now, that seems like an overkill: and caller can * add custom serializer if that is needed as well. * (ditto for null values) */ //JsonSerializer<String> ser = (JsonSerializer<String>)provider.findValueSerializer(String.class); for (int i = 0; i < len; ++i) { String str = value[i]; if (str == null) { jgen.writeNull(); } else { //ser.serialize(value[i], jgen, provider); jgen.writeString(value[i]); } } } private void serializeContentsSlow(String[] value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException, JsonGenerationException { for (int i = 0, len = value.length; i < len; ++i) { String str = value[i]; if (str == null) { provider.defaultSerializeNull(jgen); } else { ser.serialize(value[i], jgen, provider); } } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("array", true).set("items", createSchemaNode("string")); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { if (visitor != null) { JsonArrayFormatVisitor v2 = visitor.expectArrayFormat(typeHint); if (v2 != null) { v2.itemsFormat(JsonFormat

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> /* (mapping from JSON to Java types); /* main methods /********************************************************** */ /** * Method to deserialize JSON content into a non-container * type (it can be an array type, however): typically a bean, array * or a wrapper type (like {@link java.lang.Boolean}). *<p> * Note: this method should NOT be used if the result type is a * container ({@link java.util.Collection} or {@link java.util.Map}. * The reason is that due to type erasure, key and value types * can not be introspected when using this method. */ @Override @SuppressWarnings("unchecked") public <T> T readValue(JsonParser jp, Class<T> valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readValue(getDeserializationConfig(), jp, _typeFactory.constructType(valueType)); } /** * Method to deserialize JSON content into a Java type, reference * to which is passed as argument. Type is passed using so-called * "super type token" (see ) * and specifically needs to be used if the root type is a * parameterized (generic) container type. */ @Override @SuppressWarnings("unchecked") public <T> T readValue(JsonParser jp, TypeReference<?> valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readValue(getDeserializationConfig(), jp, _typeFactory.constructType(valueTypeRef)); } /** * Method to deserialize JSON content into a Java type, reference * to which is passed as argument. Type is passed using * Jackson specific type; instance of which can be constructed using * {@link TypeFactory}. */ @Override @SuppressWarnings("unchecked") public final <T> T readValue(JsonParser jp, ResolvedType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readValue(getDeserializationConfig(), jp, (JavaType) valueType); } /** * Type-safe overloaded method, basically alias for {@link #readValue(JsonParser, ResolvedType)}. */ @SuppressWarnings("unchecked") public <T> T readValue(JsonParser jp, JavaType valueType) throws IOException,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> JsonParseException, JsonMappingException { return (T) _readValue(getDeserializationConfig(), jp, valueType); } /** * Method to deserialize JSON content as tree expressed * using set of {@link JsonNode} instances. Returns * root of the resulting tree (where root can consist * of just a single node if the current event is a * value event, not container). */ @Override public <T extends TreeNode> T readTree(JsonParser jp) throws IOException, JsonProcessingException { /* 02-Mar-2009, tatu: One twist; deserialization provider * will map JSON null straight into Java null. But what * we want to return is the "null node" instead. */ /* 05-Aug-2011, tatu: Also, must check for EOF here before * calling readValue(), since that'll choke on it otherwise */ DeserializationConfig cfg = getDeserializationConfig(); JsonToken t = jp.getCurrentToken(); if (t == null) { t = jp.nextToken(); if (t == null) { return null; } } JsonNode n = (JsonNode) _readValue(cfg, jp, JSON_NODE_TYPE); if (n == null) { n = getNodeFactory().nullNode(); } @SuppressWarnings("unchecked") T result = (T) n; return result; } /** * Method for reading sequence of Objects from parser stream. * Sequence can be either root-level "unwrapped" sequence (without surrounding * JSON array), or a sequence contained in a JSON Array. * In either case {@link JsonParser} must point to the first token of * the first element, OR not point to any token (in which case it is advanced * to the next token). This means, specifically, that for wrapped sequences, * parser MUST NOT point to the surrounding <code>START_ARRAY</code> but rather * to the token following it. *<p> * Note that {@link ObjectReader} has more complete set of variants. */ @Override public <T> MappingIterator<T> readValues(JsonParser jp, ResolvedType valueType) throws IOException, JsonProcessingException { return readValues(jp,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Node.instance : n; } /** * Method to deserialize JSON content as tree expressed using set of {@link JsonNode} instances. * Returns root of the resulting tree (where root can consist of just a single node if the current * event is a value event, not container). * * @param source URL to use for fetching contents to parse as JSON for building a tree instance */ public JsonNode readTree(URL source) throws IOException, JsonProcessingException { JsonNode n = (JsonNode) _readMapAndClose(_jsonFactory.createParser(source), JSON_NODE_TYPE); return (n == null) ? NullNode.instance : n; } /* /********************************************************** /* Public API (from ObjectCodec): serialization /* (mapping from Java types to Json) /********************************************************** */ /** * Method that can be used to serialize any Java value as * JSON output, using provided {@link JsonGenerator}. */ @Override public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException { SerializationConfig config = getSerializationConfig(); // 10-Aug-2012, tatu: as per [Issue#12], must handle indentation: if (config.isEnabled(SerializationFeature.INDENT_OUTPUT)) { jgen.useDefaultPrettyPrinter(); } if (config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _writeCloseableValue(jgen, value, config); } else { _serializerProvider(config).serializeValue(jgen, value); if (config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } } } /* /********************************************************** /* Public API (from TreeCodec via ObjectCodec): Tree Model support /********************************************************** */ @Override public void writeTree(JsonGenerator jgen, TreeNode rootNode) throws IOException, JsonProcessingException { SerializationConfig config = getSerializationConfig(); _serializerProvider(config).serializeValue(jgen, rootNode); if (config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } } /** * Method to serialize given JSON Tree, using generator

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> catch (JsonProcessingException e) { throw e; } catch (IOException e) { // should not occur, no real i/o... throw new IllegalArgumentException(e.getMessage(), e); } } /** * Reverse of {@link #treeToValue}; given a value (usually bean), will * construct equivalent JSON Tree representation. Functionally similar * to serializing value into JSON and parsing JSON as tree, but * more efficient. *<p> * NOTE: one known difference from actual serialization is that so-called * "raw values" are not supported -- since they are opaque sequence of * bytes to include (which may or may not be supported by the backend) * they can not be converted using this method. It may be possible to * support conversions using full serialization, if raw values must be * preserved. * * @param <T> Actual node type; usually either basic {@link JsonNode} or * {@link com.fasterxml.jackson.databind.node.ObjectNode} * @param fromValue Bean value to convert * @return Root node of the resulting JSON tree */ @SuppressWarnings({ "unchecked", "resource" }) public <T extends JsonNode> T valueToTree(Object fromValue) throws IllegalArgumentException { if (fromValue == null) return null; TokenBuffer buf = new TokenBuffer(this, false); JsonNode result; try { writeValue(buf, fromValue); JsonParser jp = buf.asParser(); result = readTree(jp); jp.close(); } catch (IOException e) { // should not occur, no real i/o... throw new IllegalArgumentException(e.getMessage(), e); } return (T) result; } /* /********************************************************** /* Extended Public API, accessors /********************************************************** */ /** * Method that can be called to check whether mapper thinks * it could serialize an instance of given Class. * Check is done * by checking whether a serializer can be found for the type. *<p> * NOTE: since this method does NOT throw exceptions, but internal * processing may, caller usually has little information as to why * serialization would fail. * * @return True if mapper can find a serializer for instances of * given class (potentially serial

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>izable), false otherwise (not * serializable) */ public boolean canSerialize(Class<?> type) { return _serializerProvider(getSerializationConfig()).hasSerializerFor(type, null); } /** * Method similar to {@link #canSerialize(Class)} but that can return * actual {@link Throwable} that was thrown when trying to construct * serializer: this may be useful in figuring out what the actual problem is. * * @since 2.3 */ public boolean canSerialize(Class<?> type, AtomicReference<Throwable> cause) { return _serializerProvider(getSerializationConfig()).hasSerializerFor(type, cause); } /** * Method that can be called to check whether mapper thinks * it could deserialize an Object of given type. * Check is done * by checking whether a deserializer can be found for the type. * * @return True if mapper can find a serializer for instances of * given class (potentially serializable), false otherwise (not * serializable) */ public boolean canDeserialize(JavaType type) { return createDeserializationContext(null, getDeserializationConfig()).hasValueDeserializerFor(type, null); } /** * Method similar to {@link #canDeserialize(JavaType)} but that can return * actual {@link Throwable} that was thrown when trying to construct * serializer: this may be useful in figuring out what the actual problem is. * * @since 2.3 */ public boolean canDeserialize(JavaType type, AtomicReference<Throwable> cause) { return createDeserializationContext(null, getDeserializationConfig()).hasValueDeserializerFor(type, cause); } /* /********************************************************** /* Extended Public API, deserialization, /* convenience methods /********************************************************** */ @SuppressWarnings("unchecked") public <T> T readValue(File src, Class<T> valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T> T readValue(File src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public <T> T readValue(File src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public <T> T readValue(URL src, Class<T> valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T> T readValue(URL src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public <T> T readValue(URL src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public <T> T readValue(String content, Class<T> valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T> T readValue(String content, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public <T> T readValue(String content, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>(content), valueType); } @SuppressWarnings("unchecked") public <T> T readValue(Reader src, Class<T> valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T> T readValue(Reader src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public <T> T readValue(Reader src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public <T> T readValue(InputStream src, Class<T> valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T> T readValue(InputStream src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public <T> T readValue(InputStream src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public <T> T readValue(byte[] src, Class<T> valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>), _typeFactory.constructType(valueType)); } @SuppressWarnings("unchecked") public <T> T readValue(byte[] src, int offset, int len, Class<T> valueType) throws IOException, JsonParseException, JsonMappingException { // !!! TODO // _setupClassLoaderForDeserialization(valueType); return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), _typeFactory.constructType(valueType)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T> T readValue(byte[] src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings({ "unchecked", "rawtypes" }) public <T> T readValue(byte[] src, int offset, int len, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), _typeFactory.constructType(valueTypeRef)); } @SuppressWarnings("unchecked") public <T> T readValue(byte[] src, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType); } @SuppressWarnings("unchecked") public <T> T readValue(byte[] src, int offset, int len, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), valueType); } /* /********************************************************** /* Extended Public API: serialization /* (mapping from Java types to JSON) /********************************************************** */ /** * Method that can be used to serialize any Java value as * JSON output, written to File provided. */ public void writeValue(File resultFile, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_jsonFactory.createGenerator(resultFile, JsonEncoding.UTF8), value); } /**

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> * Method that can be used to serialize any Java value as * JSON output, using output stream provided (using encoding * {@link JsonEncoding#UTF8}). *<p> * Note: method does not close the underlying stream explicitly * here; however, {@link JsonFactory} this mapper uses may choose * to close the stream depending on its settings (by default, * it will try to close it when {@link JsonGenerator} we construct * is closed). */ public void writeValue(OutputStream out, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_jsonFactory.createGenerator(out, JsonEncoding.UTF8), value); } /** * Method that can be used to serialize any Java value as * JSON output, using Writer provided. *<p> * Note: method does not close the underlying stream explicitly * here; however, {@link JsonFactory} this mapper uses may choose * to close the stream depending on its settings (by default, * it will try to close it when {@link JsonGenerator} we construct * is closed). */ public void writeValue(Writer w, Object value) throws IOException, JsonGenerationException, JsonMappingException { _configAndWriteValue(_jsonFactory.createGenerator(w), value); } /** * Method that can be used to serialize any Java value as * a String. Functionally equivalent to calling * {@link #writeValue(Writer,Object)} with {@link java.io.StringWriter} * and constructing String, but more efficient. *<p> * Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it. */ @SuppressWarnings("resource") public String writeValueAsString(Object value) throws JsonProcessingException { // alas, we have to pull the recycler directly here... SegmentedStringWriter sw = new SegmentedStringWriter(_jsonFactory._getBufferRecycler()); try { _configAndWriteValue(_jsonFactory.createGenerator(sw), value); } catch (JsonProcessingException e) { // to support [JACKSON-758] throw e; } catch (IOException e) { // shouldn't really happen, but is declared as possibility so: throw JsonMappingException

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>.fromUnexpectedIOE(e); } return sw.getAndClear(); } /** * Method that can be used to serialize any Java value as * a byte array. Functionally equivalent to calling * {@link #writeValue(Writer,Object)} with {@link java.io.ByteArrayOutputStream} * and getting bytes, but more efficient. * Encoding used will be UTF-8. *<p> * Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it. */ @SuppressWarnings("resource") public byte[] writeValueAsBytes(Object value) throws JsonProcessingException { ByteArrayBuilder bb = new ByteArrayBuilder(_jsonFactory._getBufferRecycler()); try { _configAndWriteValue(_jsonFactory.createGenerator(bb, JsonEncoding.UTF8), value); } catch (JsonProcessingException e) { // to support [JACKSON-758] throw e; } catch (IOException e) { // shouldn't really happen, but is declared as possibility so: throw JsonMappingException.fromUnexpectedIOE(e); } byte[] result = bb.toByteArray(); bb.release(); return result; } /* /********************************************************** /* Extended Public API: constructing ObjectWriters /* for more advanced configuration /********************************************************** */ /** * Convenience method for constructing {@link ObjectWriter} * with default settings. */ public ObjectWriter writer() { return new ObjectWriter(this, getSerializationConfig()); } /** * Factory method for constructing {@link ObjectWriter} with * specified feature enabled (compared to settings that this * mapper instance has). */ public ObjectWriter writer(SerializationFeature feature) { return new ObjectWriter(this, getSerializationConfig().with(feature)); } /** * Factory method for constructing {@link ObjectWriter} with * specified features enabled (compared to settings that this * mapper instance has). */ public ObjectWriter writer(SerializationFeature first, SerializationFeature... other) { return new ObjectWriter(this, getSerializationConfig().with(first, other)); } /** * Factory method for constructing {@link ObjectWriter} that will * serialize objects using specified {@link DateFormat}; or, if * null passed, using timestamp

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> if (targetType != Object.class && !toValueType.hasGenericTypes() && targetType.isAssignableFrom(fromValue.getClass())) { return fromValue; } /* Then use TokenBuffer, which is a JsonGenerator: * (see [JACKSON-175]) */ TokenBuffer buf = new TokenBuffer(this, false); try { // inlined 'writeValue' with minor changes: // first: disable wrapping when writing SerializationConfig config = getSerializationConfig().without(SerializationFeature.WRAP_ROOT_VALUE); // no need to check for closing of TokenBuffer _serializerProvider(config).serializeValue(buf, fromValue); // then matching read, inlined 'readValue' with minor mods: final JsonParser jp = buf.asParser(); Object result; // ok to pass in existing feature flags; unwrapping handled by mapper final DeserializationConfig deserConfig = getDeserializationConfig(); JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { DeserializationContext ctxt = createDeserializationContext(jp, deserConfig); result = _findRootDeserializer(ctxt, toValueType).getNullValue(); } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = null; } else { // pointing to event other than null DeserializationContext ctxt = createDeserializationContext(jp, deserConfig); JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, toValueType); // note: no handling of unwarpping result = deser.deserialize(jp, ctxt); } jp.close(); return result; } catch (IOException e) { // should not occur, no real i/o... throw new IllegalArgumentException(e.getMessage(), e); } } /* /********************************************************** /* Extended Public API: JSON Schema generation /********************************************************** */ /** * Generate <a href="http://json-schema.org/">Json-schema</a> * instance for specified class. * * @param t The class to generate schema for * @return Constructed JSON schema. */ @SuppressWarnings("deprecation") public com.fasterxml.jackson.databind.jsonschema.JsonSchema generateJsonSchema(Class<?> t) throws JsonMappingException {

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> return _serializerProvider(getSerializationConfig()).generateJsonSchema(t); } /** * Method for visiting type hierarchy for given type, using specified visitor. *<p> * This method can be used for things like * generating <a href="http://json-schema.org/">Json Schema</a> * instance for specified type. * * @param type Type to generate schema for (possibly with generic signature) * * @since 2.1 */ public void acceptJsonFormatVisitor(Class<?> type, JsonFormatVisitorWrapper visitor) throws JsonMappingException { acceptJsonFormatVisitor(_typeFactory.constructType(type), visitor); } /** * Method for visiting type hierarchy for given type, using specified visitor. * Visitation uses <code>Serializer</code> hierarchy and related properties *<p> * This method can be used for things like * generating <a href="http://json-schema.org/">Json Schema</a> * instance for specified type. * * @param type Type to generate schema for (possibly with generic signature) * * @since 2.1 */ public void acceptJsonFormatVisitor(JavaType type, JsonFormatVisitorWrapper visitor) throws JsonMappingException { if (type == null) { throw new IllegalArgumentException("type must be provided"); } _serializerProvider(getSerializationConfig()).acceptJsonFormatVisitor(type, visitor); } /* /********************************************************** /* Internal methods for serialization, overridable /********************************************************** */ /** * Overridable helper method used for constructing * {@link SerializerProvider} to use for serialization. */ protected DefaultSerializerProvider _serializerProvider(SerializationConfig config) { return _serializerProvider.createInstance(config, _serializerFactory); } /** * Helper method that should return default pretty-printer to * use for generators constructed by this mapper, when instructed * to use default pretty printer. */ protected PrettyPrinter _defaultPrettyPrinter() { return _defaultPrettyPrinter; } /** * Method called to configure the generator as necessary and then * call write functionality */ protected final void _configAndWriteValue(JsonGenerator jgen, Object value) throws IOException, JsonGenerationException, JsonMappingException { Serialization

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Config cfg = getSerializationConfig(); // [JACKSON-96]: allow enabling pretty printing for ObjectMapper directly if (cfg.isEnabled(SerializationFeature.INDENT_OUTPUT)) { jgen.useDefaultPrettyPrinter(); } // [Issue#232] if (cfg.isEnabled(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN)) { jgen.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); } // [JACKSON-282]: consider Closeable if (cfg.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _configAndWriteCloseable(jgen, value, cfg); return; } boolean closed = false; try { _serializerProvider(cfg).serializeValue(jgen, value); closed = true; jgen.close(); } finally { /* won't try to close twice; also, must catch exception (so it * will not mask exception that is pending) */ if (!closed) { /* 04-Mar-2014, tatu: But! Let's try to prevent auto-closing of * structures, which typically causes more damage. */ jgen.disable(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT); try { jgen.close(); } catch (IOException ioe) { } } } } protected final void _configAndWriteValue(JsonGenerator jgen, Object value, Class<?> viewClass) throws IOException, JsonGenerationException, JsonMappingException { SerializationConfig cfg = getSerializationConfig().withView(viewClass); if (cfg.isEnabled(SerializationFeature.INDENT_OUTPUT)) { jgen.useDefaultPrettyPrinter(); } // [Issue#232] if (cfg.isEnabled(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN)) { jgen.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); } // [JACKSON-282]: consider Closeable if (cfg.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) { _configAndWriteCloseable(jgen, value, cfg); return; } boolean closed = false; try {

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> _serializerProvider(cfg).serializeValue(jgen, value); closed = true; jgen.close(); } finally { if (!closed) { // 04-Mar-2014, tatu: But! Let's try to prevent auto-closing of // structures, which typically causes more damage. jgen.disable(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT); try { jgen.close(); } catch (IOException ioe) { } } } } /** * Helper method used when value to serialize is {@link Closeable} and its <code>close()</code> * method is to be called right after serialization has been called */ private final void _configAndWriteCloseable(JsonGenerator jgen, Object value, SerializationConfig cfg) throws IOException, JsonGenerationException, JsonMappingException { Closeable toClose = (Closeable) value; try { _serializerProvider(cfg).serializeValue(jgen, value); JsonGenerator tmpJgen = jgen; jgen = null; tmpJgen.close(); Closeable tmpToClose = toClose; toClose = null; tmpToClose.close(); } finally { /* Need to close both generator and value, as long as they haven't yet * been closed */ if (jgen != null) { // 04-Mar-2014, tatu: But! Let's try to prevent auto-closing of // structures, which typically causes more damage. jgen.disable(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT); try { jgen.close(); } catch (IOException ioe) { } } if (toClose != null) { try { toClose.close(); } catch (IOException ioe) { } } } } /** * Helper method used when value to serialize is {@link Closeable} and its <code>close()</code> * method is to be called right after serialization has been called */ private final void _writeCloseableValue(JsonGenerator jgen, Object value, SerializationConfig cfg) throws IOException, JsonGenerationException, JsonMappingException { Closeable toClose = (Closeable) value; try { _serializerProvider

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>(cfg).serializeValue(jgen, value); if (cfg.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) { jgen.flush(); } Closeable tmpToClose = toClose; toClose = null; tmpToClose.close(); } finally { if (toClose != null) { try { toClose.close(); } catch (IOException ioe) { } } } } /* /********************************************************** /* Internal methods for deserialization, overridable /********************************************************** */ /** * Internal helper method called to create an instance of {@link DeserializationContext} * for deserializing a single root value. * Can be overridden if a custom context is needed. */ protected DefaultDeserializationContext createDeserializationContext(JsonParser jp, DeserializationConfig cfg) { return _deserializationContext.createInstance(cfg, jp, _injectableValues); } /** * Actual implementation of value reading+binding operation. */ protected Object _readValue(DeserializationConfig cfg, JsonParser jp, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { /* First: may need to read the next token, to initialize * state (either before first read from parser, or after * previous token has been cleared) */ Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { // [JACKSON-643]: Ask JsonDeserializer what 'null value' to use: DeserializationContext ctxt = createDeserializationContext(jp, cfg); result = _findRootDeserializer(ctxt, valueType).getNullValue(); } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = null; } else { // pointing to event other than null DeserializationContext ctxt = createDeserializationContext(jp, cfg); JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, valueType); // ok, let's get the value if (cfg.useRootWrapping()) { result = _unwrapAndDeserialize(jp, ctxt, cfg, valueType, deser); } else { result = deser.deserialize(jp, ctxt); } } // Need to consume the token

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> too jp.clearCurrentToken(); return result; } protected Object _readMapAndClose(JsonParser jp, JavaType valueType) throws IOException, JsonParseException, JsonMappingException { try { Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { // [JACKSON-643]: Ask JsonDeserializer what 'null value' to use: DeserializationContext ctxt = createDeserializationContext(jp, getDeserializationConfig()); result = _findRootDeserializer(ctxt, valueType).getNullValue(); } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = null; } else { DeserializationConfig cfg = getDeserializationConfig(); DeserializationContext ctxt = createDeserializationContext(jp, cfg); JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, valueType); if (cfg.useRootWrapping()) { result = _unwrapAndDeserialize(jp, ctxt, cfg, valueType, deser); } else { result = deser.deserialize(jp, ctxt); } ctxt.checkUnresolvedObjectId(); } // Need to consume the token too jp.clearCurrentToken(); return result; } finally { try { jp.close(); } catch (IOException ioe) { } } } /** * Method called to ensure that given parser is ready for reading * content for data binding. * * @return First token to be used for data binding after this call: * can never be null as exception will be thrown if parser can not * provide more tokens. * * @throws IOException if the underlying input source has problems during * parsing * @throws JsonParseException if parser has problems parsing content * @throws JsonMappingException if the parser does not have any more * content to map (note: Json "null" value is considered content; * enf-of-stream not) */ protected JsonToken _initForReading(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { /* First: must point to a token; if not pointing to one, advance. * This occurs before first read from JsonParser, as well as * after clearing

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> of current token. */ JsonToken t = jp.getCurrentToken(); if (t == null) { // and then we must get something... t = jp.nextToken(); if (t == null) { /* [JACKSON-546] Throw mapping exception, since it's failure to map, * not an actual parsing problem */ throw JsonMappingException.from(jp, "No content to map due to end-of-input"); } } return t; } protected Object _unwrapAndDeserialize(JsonParser jp, DeserializationContext ctxt, DeserializationConfig config, JavaType rootType, JsonDeserializer<Object> deser) throws IOException, JsonParseException, JsonMappingException { String expName = config.getRootName(); if (expName == null) { PropertyName pname = _rootNames.findRootName(rootType, config); expName = pname.getSimpleName(); } if (jp.getCurrentToken() != JsonToken.START_OBJECT) { throw JsonMappingException.from(jp, "Current token not START_OBJECT (needed to unwrap root name '" +expName+"'), but "+jp.getCurrentToken()); } if (jp.nextToken() != JsonToken.FIELD_NAME) { throw JsonMappingException.from(jp, "Current token not FIELD_NAME (to contain expected root name '" +expName+"'), but "+jp.getCurrentToken()); } String actualName = jp.getCurrentName(); if (!expName.equals(actualName)) { throw JsonMappingException.from(jp, "Root name '"+actualName+"' does not match expected ('" +expName+"') for type "+rootType); } // ok, then move to value itself.... jp.nextToken(); Object result = deser.deserialize(jp, ctxt); // and last, verify that we now get matching END_OBJECT if (jp.nextToken() != JsonToken.END_OBJECT) { throw JsonMappingException.from(jp, "Current token not END_OBJECT (to match wrapper object with root name '" +expName+"'), but "+jp.getCurrentToken()); } return result; } /* /********************************************************** /* Internal methods, other /********************************************************** */ /** * Method called to locate

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> deserializer for the passed root-level value. */ protected JsonDeserializer<Object> _findRootDeserializer(DeserializationContext ctxt, JavaType valueType) throws JsonMappingException { // First: have we already seen it? JsonDeserializer<Object> deser = _rootDeserializers.get(valueType); if (deser != null) { return deser; } // Nope: need to ask provider to resolve it deser = ctxt.findRootValueDeserializer(valueType); if (deser == null) { // can this happen? throw new JsonMappingException("Can not find a deserializer for type "+valueType); } _rootDeserializers.put(valueType, deser); return deser; } /** * @since 2.2 */ protected void _verifySchemaType(FormatSchema schema) { if (schema != null) { if (!_jsonFactory.canUseSchema(schema)) { throw new IllegalArgumentException("Can not use FormatSchema of type "+schema.getClass().getName() +" for format "+_jsonFactory.getFormatName()); } } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.jsonFormatVisitors; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; /** * Interface {@link com.fasterxml.jackson.databind.JsonSerializer} implements * to allow for visiting type hierarchy. */ public interface JsonFormatVisitable { /** * Get the representation of the schema to which this serializer will conform. * * @param typeHint Type of element (entity like property) being visited */ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> getConfig().getTimeZone(); *</pre> */ public TimeZone getTimeZone() { return _config.getTimeZone(); } /* /********************************************************** /* Public API, pass-through to DeserializerCache /********************************************************** */ @Deprecated // since 2.3, use overloaded variant public boolean hasValueDeserializerFor(JavaType type) { return hasValueDeserializerFor(type, null); } /** * Method for checking whether we could find a deserializer * for given type. * * @param type * @since 2.3 */ public boolean hasValueDeserializerFor(JavaType type, AtomicReference<Throwable> cause) { try { return _cache.hasValueDeserializerFor(this, _factory, type); } catch (JsonMappingException e) { if (cause != null) { cause.set(e); } } catch (RuntimeException e) { if (cause == null) { // earlier behavior throw e; } cause.set(e); } return false; } /** * Method for finding a value deserializer, and creating a contextual * version if necessary, for value reached via specified property. */ @SuppressWarnings("unchecked") public final JsonDeserializer<Object> findContextualValueDeserializer(JavaType type, BeanProperty prop) throws JsonMappingException { JsonDeserializer<Object> deser = _cache.findValueDeserializer(this, _factory, type); if (deser != null) { deser = (JsonDeserializer<Object>) handleSecondaryContextualization(deser, prop); } return deser; } /** * Method for finding a deserializer for root-level value. */ @SuppressWarnings("unchecked") public final JsonDeserializer<Object> findRootValueDeserializer(JavaType type) throws JsonMappingException { JsonDeserializer<Object> deser = _cache.findValueDeserializer(this, _factory, type); if (deser == null) { // can this occur? return null; } deser = (JsonDeserializer<Object>) handleSecondaryContextualization(deser, null); TypeDeserializer typeDeser = _factory.findTypeDeserializer(_config, type); if (typeDeser != null) { // important: contextualize to

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> indicate this is for root value typeDeser = typeDeser.forProperty(null); return new TypeWrappedDeserializer(typeDeser, deser); } return deser; } /** * Convenience method, functionally same as: *<pre> * getDeserializerProvider().findKeyDeserializer(getConfig(), prop.getType(), prop); *</pre> */ public final KeyDeserializer findKeyDeserializer(JavaType keyType, BeanProperty prop) throws JsonMappingException { KeyDeserializer kd = _cache.findKeyDeserializer(this, _factory, keyType); // Second: contextualize? if (kd instanceof ContextualKeyDeserializer) { kd = ((ContextualKeyDeserializer) kd).createContextual(this, prop); } return kd; } /* /********************************************************** /* Public API, ObjectId handling /********************************************************** */ /** * Method called to find and return entry corresponding to given * Object Id: will add an entry if necessary, and never returns null */ public abstract ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> generator, ObjectIdResolver resolver); @Deprecated // since 2.4 public abstract ReadableObjectId findObjectId(Object id, ObjectIdGenerator<?> generator); /** * Method called to ensure that every object id encounter during processing * are resolved. * * @throws UnresolvedForwardReference */ public abstract void checkUnresolvedObjectId() throws UnresolvedForwardReference; /* /********************************************************** /* Public API, type handling /********************************************************** */ /** * Convenience method, functionally equivalent to: *<pre> * getConfig().constructType(cls); * </pre> */ public final JavaType constructType(Class<?> cls) { return _config.constructType(cls); } /** * Helper method to use for locating Class for given name. Should be used * instead of basic <code>Class.forName(className);</code> as it can * try using contextual class loader, or use platform-specific workarounds * (like on Android, GAE). */ public Class<?> findClass(String className) throws ClassNotFoundException { // By default, delegate to ClassUtil: can be overridden with custom handling return ClassUtil.findClass(className);

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } /* /********************************************************** /* Public API, helper object recycling /********************************************************** */ /** * Method that can be used to get access to a reusable ObjectBuffer, * useful for efficiently constructing Object arrays and Lists. * Note that leased buffers should be returned once deserializer * is done, to allow for reuse during same round of deserialization. */ public final ObjectBuffer leaseObjectBuffer() { ObjectBuffer buf = _objectBuffer; if (buf == null) { buf = new ObjectBuffer(); } else { _objectBuffer = null; } return buf; } /** * Method to call to return object buffer previously leased with * {@link #leaseObjectBuffer}. * * @param buf Returned object buffer */ public final void returnObjectBuffer(ObjectBuffer buf) { /* Already have a reusable buffer? Let's retain bigger one * (or if equal, favor newer one, shorter life-cycle) */ if (_objectBuffer == null || buf.initialCapacity() >= _objectBuffer.initialCapacity()) { _objectBuffer = buf; } } /** * Method for accessing object useful for building arrays of * primitive types (such as int[]). */ public final ArrayBuilders getArrayBuilders() { if (_arrayBuilders == null) { _arrayBuilders = new ArrayBuilders(); } return _arrayBuilders; } /* /********************************************************** /* Extended API: handler instantiation /********************************************************** */ public abstract JsonDeserializer<Object> deserializerInstance(Annotated annotated, Object deserDef) throws JsonMappingException; public abstract KeyDeserializer keyDeserializerInstance(Annotated annotated, Object deserDef) throws JsonMappingException; /* /********************************************************** /* Extended API: resolving contextual deserializers; called /* by structured deserializers for their value/component /* deserializers /********************************************************** */ /** * Method called for primary property deserializers (ones * directly created to deserialize values of a POJO property), * to handle details of resolving * {@link ContextualDeserializer} with given property context. * * @param prop Property for which the given primary deserializer is used; never null. * * @since 2.3 */ public JsonDeserializer

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS><?> handlePrimaryContextualization(JsonDeserializer<?> deser, BeanProperty prop) throws JsonMappingException { if (deser != null) { if (deser instanceof ContextualDeserializer) { deser = ((ContextualDeserializer) deser).createContextual(this, prop); } } return deser; } /** * Method called for secondary property deserializers (ones * NOT directly created to deal with an annotatable POJO property, * but instead created as a component -- such as value deserializers * for structured types, or deserializers for root values) * to handle details of resolving * {@link ContextualDeserializer} with given property context. * Given that these deserializers are not directly related to given property * (or, in case of root value property, to any property), annotations * accessible may or may not be relevant. * * @param prop Property for which deserializer is used, if any; null * when deserializing root values * * @since 2.3 */ public JsonDeserializer<?> handleSecondaryContextualization(JsonDeserializer<?> deser, BeanProperty prop) throws JsonMappingException { if (deser != null && (deser instanceof ContextualDeserializer)) { deser = ((ContextualDeserializer) deser).createContextual(this, prop); } return deser; } /* /********************************************************** /* Parsing methods that may use reusable/-cyclable objects /********************************************************** */ /** * Convenience method for parsing a Date from given String, using * currently configured date format (accessed using * {@link DeserializationConfig#getDateFormat()}). *<p> * Implementation will handle thread-safety issues related to * date formats such that first time this method is called, * date format is cloned, and cloned instance will be retained * for use during this deserialization round. */ public Date parseDate(String dateStr) throws IllegalArgumentException { try { DateFormat df = getDateFormat(); return df.parse(dateStr); } catch (ParseException e) { throw new IllegalArgumentException("Failed to parse Date value '"+dateStr+"': "+e.getMessage()); } } /** * Convenience method for constructing Calendar instance set * to specified time, to be modified and used by caller. */ public

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>deserialize(p, this); } /* /********************************************************** /* Methods for problem handling, reporting /********************************************************** */ /** * Method deserializers can call to inform configured {@link DeserializationProblemHandler}s * of an unrecognized property. * * @return True if there was a configured problem handler that was able to handle the * problem */ /** * Method deserializers can call to inform configured {@link DeserializationProblemHandler}s * of an unrecognized property. */ public boolean handleUnknownProperty(JsonParser p, JsonDeserializer<?> deser, Object instanceOrClass, String propName) throws IOException, JsonProcessingException { LinkedNode<DeserializationProblemHandler> h = _config.getProblemHandlers(); if (h != null) { while (h != null) { // Can bail out if it's handled if (h.value().handleUnknownProperty(this, p, deser, instanceOrClass, propName)) { return true; } h = h.next(); } } return false; } /** * Helper method for reporting a problem with unhandled unknown exception * * @param instanceOrClass Either value being populated (if one has been * instantiated), or Class that indicates type that would be (or * have been) instantiated * @param deser Deserializer that had the problem, if called by deserializer * (or on behalf of one) */ public void reportUnknownProperty(Object instanceOrClass, String fieldName, JsonDeserializer<?> deser) throws JsonMappingException { if (!isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) { return; } // Do we know properties that are expected instead? Collection<Object> propIds = (deser == null) ? null : deser.getKnownPropertyNames(); throw UnrecognizedPropertyException.from(_parser, instanceOrClass, fieldName, propIds); } /* /********************************************************** /* Methods for constructing exceptions /********************************************************** */ /** * Helper method for constructing generic mapping exception for specified type */ public JsonMappingException mappingException(Class<?> targetClass) { return mappingException(targetClass, _parser.getCurrentToken()); } public JsonMappingException mappingException(Class<?> targetClass, JsonToken token)

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> { return JsonMappingException.from(_parser, "Can not deserialize instance of "+_calcName(targetClass)+" out of "+token+" token"); } /** * Helper method for constructing generic mapping exception with specified * message and current location information */ public JsonMappingException mappingException(String message) { return JsonMappingException.from(getParser(), message); } /** * Helper method for constructing instantiation exception for specified type, * to indicate problem with physically constructing instance of * specified class (missing constructor, exception from constructor) */ public JsonMappingException instantiationException(Class<?> instClass, Throwable t) { return JsonMappingException.from(_parser, "Can not construct instance of "+instClass.getName()+", problem: "+t.getMessage(), t); } public JsonMappingException instantiationException(Class<?> instClass, String msg) { return JsonMappingException.from(_parser, "Can not construct instance of "+instClass.getName()+", problem: "+msg); } /** * Method that will construct an exception suitable for throwing when * some String values are acceptable, but the one encountered is not. * * * @deprecated Since 2.1 should use variant that takes value */ @Deprecated public JsonMappingException weirdStringException(Class<?> instClass, String msg) { return weirdStringException(null, instClass, msg); } /** * Method that will construct an exception suitable for throwing when * some String values are acceptable, but the one encountered is not. * * @param value String value from input being deserialized * @param instClass Type that String should be deserialized into * @param msg Message that describes specific problem * * @since 2.1 */ public JsonMappingException weirdStringException(String value, Class<?> instClass, String msg) { return InvalidFormatException.from(_parser, "Can not construct instance of "+instClass.getName()+" from String value '"+_valueDesc()+"': "+msg, value, instClass); } /** * Helper method for constructing exception to indicate that input JSON * Number was not suitable for deserializing into given type. */ @Deprecated public JsonMappingException weirdNumberException(Class<?> instClass, String msg) { return weirdStringException(null, instClass,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> msg); } /** * Helper method for constructing exception to indicate that input JSON * Number was not suitable for deserializing into given target type. */ public JsonMappingException weirdNumberException(Number value, Class<?> instClass, String msg) { return InvalidFormatException.from(_parser, "Can not construct instance of "+instClass.getName()+" from number value ("+_valueDesc()+"): "+msg, null, instClass); } /** * Helper method for constructing exception to indicate that given JSON * Object field name was not in format to be able to deserialize specified * key type. */ public JsonMappingException weirdKeyException(Class<?> keyClass, String keyValue, String msg) { return InvalidFormatException.from(_parser, "Can not construct Map key of type "+keyClass.getName()+" from String \""+_desc(keyValue)+"\": "+msg, keyValue, keyClass); } /** * Helper method for indicating that the current token was expected to be another * token. */ public JsonMappingException wrongTokenException(JsonParser p, JsonToken expToken, String msg0) { String msg = "Unexpected token ("+p.getCurrentToken()+"), expected "+expToken; if (msg0 != null) { msg = msg + ": "+msg0; } return JsonMappingException.from(p, msg); } /** * Helper method for constructing exception to indicate that given * type id (parsed from JSON) could not be converted to a Java type. */ public JsonMappingException unknownTypeException(JavaType type, String id) { return JsonMappingException.from(_parser, "Could not resolve type id '"+id+"' into a subtype of "+type); } public JsonMappingException endOfInputException(Class<?> instClass) { return JsonMappingException.from(_parser, "Unexpected end-of-input when trying to deserialize a " +instClass.getName()); } /* /********************************************************** /* Overridable internal methods /********************************************************** */ protected DateFormat getDateFormat() { if (_dateFormat != null) { return _dateFormat; } /* 24-Feb-2012, tatu: At this point, all timezone configuration * should have occured, with respect to

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> default dateformat * and timezone configuration. But we still better clone * an instance as formatters may be stateful. */ DateFormat df = _config.getDateFormat(); _dateFormat = df = (DateFormat) df.clone(); return df; } protected String determineClassName(Object instance) { return ClassUtil.getClassDescription(instance); } /* /********************************************************** /* Other internal methods /********************************************************** */ protected String _calcName(Class<?> cls) { if (cls.isArray()) { return _calcName(cls.getComponentType())+"[]"; } return cls.getName(); } protected String _valueDesc() { try { return _desc(_parser.getText()); } catch (Exception e) { return "[N/A]"; } } protected String _desc(String desc) { // !!! should we quote it? (in case there are control chars, linefeeds) if (desc.length() > MAX_ERROR_STR_LEN) { desc = desc.substring(0, MAX_ERROR_STR_LEN) + "]...[" + desc.substring(desc.length() - MAX_ERROR_STR_LEN); } return desc; } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; /** * Abstract class that defines API used by {@link SerializerProvider} * to obtain actual * {@link JsonSerializer} instances from multiple distinct factories. */ public abstract class SerializerFactory { /* /********************************************************** /* Additional configuration methods /********************************************************** */ /** * Convenience method for creating a new factory instance with additional serializer * provider; equivalent to calling *<pre> * withConfig(getConfig().withAdditionalSerializers(additional)); *<pre> */ public abstract SerializerFactory withAdditionalSerializers(Serializers additional); public abstract SerializerFactory withAdditionalKeySerializers(Serializers additional); /** * Convenience method for creating a new factory instance with additional bean * serializer modifier; equivalent to calling *<pre> * withConfig(getConfig().withSerializerModifier(modifier)); *<pre> */ public abstract SerializerFactory withSerializerModifier(BeanSerializerModifier modifier); /* /********************************************************** /* Basic SerializerFactory API: /********************************************************** */ /** * Method called to create (or, for immutable serializers, reuse) a serializer for given type. * * @param prov Provider that needs to be used to resolve annotation-provided * serializers (but NOT for others) * * @since 2.1 (earlier versions had method with different signature) */ public abstract JsonSerializer<Object> createSerializer(SerializerProvider prov, JavaType baseType) throws JsonMappingException; /** * Method called to create a type information serializer for given base type, * if one is needed. If not needed (no polymorphic handling configured), should * return null. * * @param baseType Declared type to use as the base type for type information serializer * * @return Type serializer to use for the base type, if one is needed; null if not. */ public abstract TypeSerializer createTypeSerializer(SerializationConfig config, JavaType baseType) throws JsonMappingException; /** * Method called to create serializer to use for serializing JSON property names (which must * be output as <code>JsonToken.FIELD_NAME</code>) for Map

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> that has specified declared * key type, and is for specified property (or, if property is null, as root value) * * @param baseType Declared type for Map keys * @param defaultImpl Default key serializer implementation to use, if no custom ones * are found (may be null) * * @return Serializer to use, if factory knows it; null if not (in which case default * serializer is to be used) */ public abstract JsonSerializer<Object> createKeySerializer(SerializationConfig config, JavaType baseType, JsonSerializer<Object> defaultImpl) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> Enum<T>>" etc) bindings._addPlaceholder(name); // About only useful piece of information is the lower bound (which is at least Object.class) Type lowerBound = var.getBounds()[0]; JavaType type = (lowerBound == null) ? TypeFactory.unknownType() : bindings.resolveType(lowerBound); bindings.addBinding(var.getName(), type); } } return bindings.resolveType(getGenericType()); } /* /********************************************************** /* Partial Annotated impl /********************************************************** */ @Override public final <A extends Annotation> A getAnnotation(Class<A> acls) { return _annotations.get(acls); } /* /********************************************************** /* Extended API /********************************************************** */ public final AnnotationMap getParameterAnnotations(int index) { if (_paramAnnotations != null) { if (index >= 0 && index <= _paramAnnotations.length) { return _paramAnnotations[index]; } } return null; } public final AnnotatedParameter getParameter(int index) { return new AnnotatedParameter(this, getGenericParameterType(index), getParameterAnnotations(index), index); } public abstract int getParameterCount(); public abstract Class<?> getRawParameterType(int index); public abstract Type getGenericParameterType(int index); /** * Method called to fully resolve type of one of parameters, given * specified type variable bindings. */ public final JavaType resolveParameterType(int index, TypeBindings bindings) { return bindings.resolveType(getGenericParameterType(index)); } public final int getAnnotationCount() { return _annotations.size(); } /** * Method that can be used to (try to) call this object without arguments. * This may succeed or fail, depending on expected number * of arguments: caller needs to take care to pass correct number. * Exceptions are thrown directly from actual low-level call. *<p> * Note: only works for constructors and static methods. */ public abstract Object call() throws Exception; /** * Method that can be used to (try to) call this object with specified arguments. * This may succeed or fail, depending on expected number * of arguments: caller needs to take care to pass correct number.

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> * Exceptions are thrown directly from actual low-level call. *<p> * Note: only works for constructors and static methods. */ public abstract Object call(Object[] args) throws Exception; /** * Method that can be used to (try to) call this object with single arguments. * This may succeed or fail, depending on expected number * of arguments: caller needs to take care to pass correct number. * Exceptions are thrown directly from actual low-level call. *<p> * Note: only works for constructors and static methods. */ public abstract Object call1(Object arg) throws Exception; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> serializer definitions"); } return new BeanSerializerFactory(config); } @Override protected Iterable<Serializers> customSerializers() { return _factoryConfig.serializers(); } /* /********************************************************** /* SerializerFactory impl /********************************************************** */ /** * Main serializer constructor method. We will have to be careful * with respect to ordering of various method calls: essentially * we want to reliably figure out which classes are standard types, * and which are beans. The problem is that some bean Classes may * implement standard interfaces (say, {@link java.lang.Iterable}. *<p> * Note: sub-classes may choose to complete replace implementation, * if they want to alter priority of serializer lookups. */ @Override @SuppressWarnings("unchecked") public JsonSerializer<Object> createSerializer(SerializerProvider prov, JavaType origType) throws JsonMappingException { // Very first thing, let's check if there is explicit serializer annotation: final SerializationConfig config = prov.getConfig(); BeanDescription beanDesc = config.introspect(origType); JsonSerializer<?> ser = findSerializerFromAnnotation(prov, beanDesc.getClassInfo()); if (ser != null) { return (JsonSerializer<Object>) ser; } boolean staticTyping; // Next: we may have annotations that further define types to use... JavaType type = modifyTypeByAnnotation(config, beanDesc.getClassInfo(), origType); if (type == origType) { // no changes, won't force static typing staticTyping = false; } else { // changes; assume static typing; plus, need to re-introspect if class differs staticTyping = true; if (!type.hasRawClass(origType.getRawClass())) { beanDesc = config.introspect(type); } } // Slight detour: do we have a Converter to consider? Converter<Object,Object> conv = beanDesc.findSerializationConverter(); if (conv == null) { // no, simple return (JsonSerializer<Object>) _createSerializer2(prov, type, beanDesc, staticTyping); } JavaType delegateType = conv.getOutputType(prov.getTypeFactory()); // One more twist, as per [Issue#288]; probably need to get new Bean

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Desc if (!delegateType.hasRawClass(type.getRawClass())) { beanDesc = config.introspect(delegateType); // [#359]: explicitly check (again) for @JsonSerializer... ser = findSerializerFromAnnotation(prov, beanDesc.getClassInfo()); } if (ser == null) { ser = _createSerializer2(prov, delegateType, beanDesc, true); } return new StdDelegatingSerializer(conv, delegateType, ser); } protected JsonSerializer<?> _createSerializer2(SerializerProvider prov, JavaType type, BeanDescription beanDesc, boolean staticTyping) throws JsonMappingException { // Then JsonSerializable, @JsonValue etc: JsonSerializer<?> ser = findSerializerByAnnotations(prov, type, beanDesc); if (ser != null) { return ser; } final SerializationConfig config = prov.getConfig(); // Container types differ from non-container types // (note: called method checks for module-provided serializers) if (type.isContainerType()) { if (!staticTyping) { staticTyping = usesStaticTyping(config, beanDesc, null); // [Issue#23]: Need to figure out how to force passed parameterization // to stick... /* if (property == null) { JavaType t = origType.getContentType(); if (t != null && !t.hasRawClass(Object.class)) { staticTyping = true; } } */ } // 03-Aug-2012, tatu: As per [Issue#40], may require POJO serializer... ser = buildContainerSerializer(prov, type, beanDesc, staticTyping); // Will return right away, since called method does post-processing: if (ser != null) { return ser; } } else { // Modules may provide serializers of POJO types: for (Serializers serializers : customSerializers()) { ser = serializers.findSerializer(config, type, beanDesc); if (ser != null) { break; } } } // Otherwise, we will check "primary types"; both marker types that // indicate specific handling (JsonSerializable), or main types that have // precedence over container types if (ser == null) { ser =

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> findSerializerByLookup(type, config, beanDesc, staticTyping); if (ser == null) { ser = findSerializerByPrimaryType(prov, type, beanDesc, staticTyping); if (ser == null) { // And this is where this class comes in: if type is not a // known "primary JDK type", perhaps it's a bean? We can still // get a null, if we can't find a single suitable bean property. ser = findBeanSerializer(prov, type, beanDesc); // Finally: maybe we can still deal with it as an implementation of some basic JDK interface? if (ser == null) { ser = findSerializerByAddonType(config, type, beanDesc, staticTyping); } } } } if (ser != null) { // [Issue#120]: Allow post-processing if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { ser = mod.modifySerializer(config, beanDesc, ser); } } } return ser; } /* /********************************************************** /* Other public methods that are not part of /* JsonSerializerFactory API /********************************************************** */ /** * Method that will try to construct a {@link BeanSerializer} for * given class. Returns null if no properties are found. */ public JsonSerializer<Object> findBeanSerializer(SerializerProvider prov, JavaType type, BeanDescription beanDesc) throws JsonMappingException { // First things first: we know some types are not beans... if (!isPotentialBeanType(type.getRawClass())) { // 03-Aug-2012, tatu: Except we do need to allow serializers for Enums, // as per [Issue#24] if (!type.isEnumType()) { return null; } } return constructBeanSerializer(prov, beanDesc); } /** * Method called to create a type information serializer for values of given * non-container property * if one is needed. If not needed (no polymorphic handling configured), should * return null. * * @param baseType Declared type to use as the base type for type information serializer * * @return Type serializer to use for property values

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>, if one is needed; null if not. */ public TypeSerializer findPropertyTypeSerializer(JavaType baseType, SerializationConfig config, AnnotatedMember accessor) throws JsonMappingException { AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findPropertyTypeResolver(config, accessor, baseType); // Defaulting: if no annotations on member, check value class if (b == null) { return createTypeSerializer(config, baseType); } Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypes( accessor, config, ai, baseType); return b.buildTypeSerializer(config, baseType, subtypes); } /** * Method called to create a type information serializer for values of given * container property * if one is needed. If not needed (no polymorphic handling configured), should * return null. * * @param containerType Declared type of the container to use as the base type for type information serializer * * @return Type serializer to use for property value contents, if one is needed; null if not. */ public TypeSerializer findPropertyContentTypeSerializer(JavaType containerType, SerializationConfig config, AnnotatedMember accessor) throws JsonMappingException { JavaType contentType = containerType.getContentType(); AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, accessor, containerType); // Defaulting: if no annotations on member, check value class if (b == null) { return createTypeSerializer(config, contentType); } Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypes(accessor, config, ai, contentType); return b.buildTypeSerializer(config, contentType, subtypes); } /* /********************************************************** /* Overridable non-public factory methods /********************************************************** */ /** * Method called to construct serializer for serializing specified bean type. * * @since 2.1 */ @SuppressWarnings("unchecked") protected JsonSerializer<Object> constructBeanSerializer(SerializerProvider prov, BeanDescription beanDesc) throws JsonMappingException { // 13-Oct-2010, tatu

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>PING); JavaType valueType = type.getContentType(); TypeSerializer typeSer = createTypeSerializer(config, valueType); // last 2 nulls; don't know key, value serializers (yet) // TODO: support '@JsonIgnoreProperties' with any setter? MapSerializer mapSer = MapSerializer.construct(/* ignored props*/ null, type, staticTyping, typeSer, null, null, /*filterId*/ null); // TODO: can we find full PropertyName? PropertyName name = new PropertyName(anyGetter.getName()); BeanProperty.Std anyProp = new BeanProperty.Std(name, valueType, null, beanDesc.getClassAnnotations(), anyGetter, PropertyMetadata.STD_OPTIONAL); builder.setAnyGetter(new AnyGetterWriter(anyProp, anyGetter, mapSer)); } // Next: need to gather view information, if any: processViews(config, builder); // Finally: let interested parties mess with the result bit more... if (_factoryConfig.hasSerializerModifiers()) { for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) { builder = mod.updateBuilder(config, beanDesc, builder); } } JsonSerializer<Object> ser = (JsonSerializer<Object>) builder.build(); /* However, after all modifications: no properties, no serializer * (note; as per [JACKSON-670], check was moved later on from an earlier location) */ if (ser == null) { /* 27-Nov-2009, tatu: Except that as per [JACKSON-201], we are * ok with that as long as it has a recognized class annotation * (which may come from a mix-in too) */ if (beanDesc.hasKnownClassAnnotations()) { return builder.createDummy(); } } return ser; } protected ObjectIdWriter constructObjectIdHandler(SerializerProvider prov, BeanDescription beanDesc, List<BeanPropertyWriter> props) throws JsonMappingException { ObjectIdInfo objectIdInfo = beanDesc.getObjectIdInfo(); if (objectIdInfo == null) { return null; } ObjectIdGenerator<?> gen; Class<?> implClass = objectIdInfo.getGeneratorType(); // Just one special case: Property-

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>); } protected BeanSerializerBuilder constructBeanSerializerBuilder(BeanDescription beanDesc) { return new BeanSerializerBuilder(beanDesc); } /* /********************************************************** /* Overridable non-public introspection methods /********************************************************** */ /** * Helper method used to skip processing for types that we know * can not be (i.e. are never consider to be) beans: * things like primitives, Arrays, Enums, and proxy types. *<p> * Note that usually we shouldn't really be getting these sort of * types anyway; but better safe than sorry. */ protected boolean isPotentialBeanType(Class<?> type) { return (ClassUtil.canBeABeanType(type) == null) && !ClassUtil.isProxyType(type); } /** * Method used to collect all actual serializable properties. * Can be overridden to implement custom detection schemes. */ protected List<BeanPropertyWriter> findBeanProperties(SerializerProvider prov, BeanDescription beanDesc, BeanSerializerBuilder builder) throws JsonMappingException { List<BeanPropertyDefinition> properties = beanDesc.findProperties(); final SerializationConfig config = prov.getConfig(); // [JACKSON-429]: ignore specified types removeIgnorableTypes(config, beanDesc, properties); // and possibly remove ones without matching mutator... if (config.isEnabled(MapperFeature.REQUIRE_SETTERS_FOR_GETTERS)) { removeSetterlessGetters(config, beanDesc, properties); } // nothing? can't proceed (caller may or may not throw an exception) if (properties.isEmpty()) { return null; } // null is for value type serializer, which we don't have access to from here (ditto for bean prop) boolean staticTyping = usesStaticTyping(config, beanDesc, null); PropertyBuilder pb = constructPropertyBuilder(config, beanDesc); ArrayList<BeanPropertyWriter> result = new ArrayList<BeanPropertyWriter>(properties.size()); TypeBindings typeBind = beanDesc.bindingsForBeanType(); for (BeanPropertyDefinition property : properties) { final AnnotatedMember accessor = property.getAccessor(); // [JACKSON-762]: type id? Requires special handling: if (property.is

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>-ignorable if (result == null) { result = Boolean.FALSE; } ignores.put(type, result); } // lotsa work, and yes, it is ignorable type, so: if (result.booleanValue()) { it.remove(); } } } /** * Helper method that will remove all properties that do not have a mutator. */ protected void removeSetterlessGetters(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyDefinition> properties) { Iterator<BeanPropertyDefinition> it = properties.iterator(); while (it.hasNext()) { BeanPropertyDefinition property = it.next(); // one caveat: as per [JACKSON-806], only remove implicit properties; // explicitly annotated ones should remain if (!property.couldDeserialize() && !property.isExplicitlyIncluded()) { it.remove(); } } } /* /********************************************************** /* Internal helper methods /********************************************************** */ /** * Secondary helper method for constructing {@link BeanPropertyWriter} for * given member (field or method). */ protected BeanPropertyWriter _constructWriter(SerializerProvider prov, BeanPropertyDefinition propDef, TypeBindings typeContext, PropertyBuilder pb, boolean staticTyping, AnnotatedMember accessor) throws JsonMappingException { final PropertyName name = propDef.getFullName(); if (prov.canOverrideAccessModifiers()) { accessor.fixAccess(); } JavaType type = accessor.getType(typeContext); BeanProperty.Std property = new BeanProperty.Std(name, type, propDef.getWrapperName(), pb.getClassAnnotations(), accessor, propDef.getMetadata()); // Does member specify a serializer? If so, let's use it. JsonSerializer<?> annotatedSerializer = findSerializerFromAnnotation(prov, accessor); /* 02-Feb-2012, tatu: Unlike most other code paths, serializer produced * here will NOT be resolved or contextualized, unless done here, so: */ if (annotatedSerializer instanceof ResolvableSerializer) { ((ResolvableSerializer) annotatedSerializer).resolve(prov); } // 05-Sep-2013, tatu: should be primary property serializer so: annotatedSerializer = prov

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> sers.put(Void.class, NullSerializer.instance); sers.put(Void.TYPE, NullSerializer.instance); return sers.entrySet(); } /* /********************************************************** /* Serializers for atomic types /********************************************************** */ public final static class AtomicBooleanSerializer extends StdScalarSerializer<AtomicBoolean> { public AtomicBooleanSerializer() { super(AtomicBoolean.class, false); } @Override public void serialize(AtomicBoolean value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeBoolean(value.get()); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("boolean", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { visitor.expectBooleanFormat(typeHint); } } public final static class AtomicIntegerSerializer extends StdScalarSerializer<AtomicInteger> { public AtomicIntegerSerializer() { super(AtomicInteger.class, false); } @Override public void serialize(AtomicInteger value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeNumber(value.get()); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("integer", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint); if (v2 != null) { v2.numberType(JsonParser.NumberType.INT); } } } public final static class AtomicLongSerializer extends StdScalarSerializer<AtomicLong> { public AtomicLongSerializer() { super(AtomicLong.class, false); } @Override public void serialize(AtomicLong value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeNumber(value.get()); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("integer", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> JavaType typeHint) throws JsonMappingException { JsonIntegerFormatVisitor v2 = visitor.expectIntegerFormat(typeHint); if (v2 != null) { v2.numberType(JsonParser.NumberType.LONG); } } } public final static class AtomicReferenceSerializer extends StdSerializer<AtomicReference<?>> { public AtomicReferenceSerializer() { super(AtomicReference.class, false); } @Override public void serialize(AtomicReference<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { provider.defaultSerializeValue(value.get(), jgen); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("any", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { visitor.expectAnyFormat(typeHint); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> if (m != null) { AnnotatedMethod am = _constructMethod(m); _addMixOvers(mixIn.getAnnotated(), am, false); _memberMethods.add(am); } } catch (Exception e) { } } } } } /** * Method that will collect all member (non-static) fields * that are either public, or have at least a single annotation * associated with them. */ private void resolveFields() { Map<String,AnnotatedField> foundFields = _findFields(_class, null); if (foundFields == null || foundFields.size() == 0) { _fields = Collections.emptyList(); } else { _fields = new ArrayList<AnnotatedField>(foundFields.size()); _fields.addAll(foundFields.values()); } } /* /********************************************************** /* Helper methods for resolving class annotations /* (resolution consisting of inheritance, overrides, /* and injection of mix-ins as necessary) /********************************************************** */ /** * Helper method for adding any mix-in annotations specified * class might have. */ protected void _addClassMixIns(AnnotationMap annotations, Class<?> toMask) { if (_mixInResolver != null) { _addClassMixIns(annotations, toMask, _mixInResolver.findMixInClassFor(toMask)); } } protected void _addClassMixIns(AnnotationMap annotations, Class<?> toMask, Class<?> mixin) { if (mixin == null) { return; } // Ok, first: annotations from mix-in class itself: _addAnnotationsIfNotPresent(annotations, mixin.getDeclaredAnnotations()); /* And then from its supertypes, if any. But note that we will * only consider super-types up until reaching the masked * class (if found); this because often mix-in class * is a sub-class (for convenience reasons). And if so, we * absolutely must NOT include super types of masked class, * as that would inverse precedence of annotations. */ for (Class<?> parent : ClassUtil.findSuperTypes(mixin, toMask)) { _addAnnotationsIfNotPresent(annotations, parent.getDeclaredAnnotations()); } } /* /********************************************************** /* Helper

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>(_delegate.withIgnorableProperties(ignorableProps), _orderedProperties); } @Override protected BeanDeserializerBase asArrayDeserializer() { return this; } /* /********************************************************** /* JsonDeserializer implementation /********************************************************** */ @Override public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // Let's delegate just in case we got a JSON Object (could error out, alternatively?) if (jp.getCurrentToken() != JsonToken.START_ARRAY) { return _deserializeFromNonArray(jp, ctxt); } if (!_vanillaProcessing) { return _deserializeNonVanilla(jp, ctxt); } final Object bean = _valueInstantiator.createUsingDefault(ctxt); final SettableBeanProperty[] props = _orderedProperties; int i = 0; final int propCount = props.length; while (true) { if (jp.nextToken() == JsonToken.END_ARRAY) { return bean; } if (i == propCount) { break; } SettableBeanProperty prop = props[i]; if (prop != null) { // normal case try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, prop.getName(), ctxt); } } else { // just skip? jp.skipChildren(); } ++i; } // Ok; extra fields? Let's fail, unless ignoring extra props is fine if (!_ignoreAllUnknown) { throw ctxt.mappingException("Unexpected JSON values; expected at most "+propCount+" properties (in JSON Array)"); } // otherwise, skip until end while (jp.nextToken() != JsonToken.END_ARRAY) { jp.skipChildren(); } return bean; } @Override public Object deserialize(JsonParser jp, DeserializationContext ctxt, Object bean) throws IOException, JsonProcessingException { /* No good way to verify that we have an array... although could I guess * check via JsonParser. So let's assume everything is working fine, for now. */ if (_injectables != null) { injectValues(ctxt, bean); } final SettableBeanProperty[] props

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> = _orderedProperties; int i = 0; final int propCount = props.length; while (true) { if (jp.nextToken() == JsonToken.END_ARRAY) { return bean; } if (i == propCount) { break; } SettableBeanProperty prop = props[i]; if (prop != null) { // normal case try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, prop.getName(), ctxt); } } else { // just skip? jp.skipChildren(); } ++i; } // Ok; extra fields? Let's fail, unless ignoring extra props is fine if (!_ignoreAllUnknown) { throw ctxt.mappingException("Unexpected JSON values; expected at most "+propCount+" properties (in JSON Array)"); } // otherwise, skip until end while (jp.nextToken() != JsonToken.END_ARRAY) { jp.skipChildren(); } return bean; } // needed since 2.1 @Override public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { return _deserializeFromNonArray(jp, ctxt); } /* /********************************************************** /* Helper methods, non-standard creation /********************************************************** */ /** * Alternate deserialization method that has to check many more configuration * aspects than the "vanilla" processing. */ protected Object _deserializeNonVanilla(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (_nonStandardCreation) { return _deserializeWithCreator(jp, ctxt); } final Object bean = _valueInstantiator.createUsingDefault(ctxt); if (_injectables != null) { injectValues(ctxt, bean); } Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null; final SettableBeanProperty[] props = _orderedProperties; int i = 0; final int propCount = props.length; while (true) { if (jp.nextToken() == JsonToken.END_ARRAY) { return bean; } if (i == propCount) { break

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>; } SettableBeanProperty prop = props[i]; ++i; if (prop != null) { // normal case if (activeView == null || prop.visibleInView(activeView)) { try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, prop.getName(), ctxt); } continue; } } // otherwise, skip it (view-filtered, no prop etc) jp.skipChildren(); } // Ok; extra fields? Let's fail, unless ignoring extra props is fine if (!_ignoreAllUnknown) { throw ctxt.mappingException("Unexpected JSON values; expected at most "+propCount+" properties (in JSON Array)"); } // otherwise, skip until end while (jp.nextToken() != JsonToken.END_ARRAY) { jp.skipChildren(); } return bean; } protected Object _deserializeWithCreator(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (_delegateDeserializer != null) { return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); } if (_propertyBasedCreator != null) { return _deserializeUsingPropertyBased(jp, ctxt); } // should only occur for abstract types... if (_beanType.isAbstract()) { throw JsonMappingException.from(jp, "Can not instantiate abstract type "+_beanType +" (need to add/enable type information?)"); } throw JsonMappingException.from(jp, "No suitable constructor found for type " +_beanType+": can not instantiate from JSON object (need to add/enable type information?)"); } /** * Method called to deserialize bean using "property-based creator": * this means that a non-default constructor or factory method is * called, and then possibly other setters. The trick is that * values for creator method need to be buffered, first; and * due to non-guaranteed ordering possibly some other properties * as well. */ @Override protected final Object _deserializeUsingPropertyBased(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException { final PropertyBasedCreator creator = _propertyBasedCreator

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>; PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader); final SettableBeanProperty[] props = _orderedProperties; final int propCount = props.length; int i = 0; Object bean = null; for (; jp.nextToken() != JsonToken.END_ARRAY; ++i) { SettableBeanProperty prop = (i < propCount) ? props[i] : null; if (prop == null) { // we get null if there are extra elements; maybe otherwise too? jp.skipChildren(); continue; } // if we have already constructed POJO, things are simple: if (bean != null) { try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, prop.getName(), ctxt); } continue; } final String propName = prop.getName(); // if not yet, maybe we got a creator property? SettableBeanProperty creatorProp = creator.findCreatorProperty(propName); if (creatorProp != null) { // Last creator property to set? Object value = creatorProp.deserialize(jp, ctxt); if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) { try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt); continue; // never gets here } // polymorphic? if (bean.getClass() != _beanType.getRawClass()) { /* 23-Jul-2012, tatu: Not sure if these could ever be properly * supported (since ordering of elements may not be guaranteed); * but make explicitly non-supported for now. */ throw ctxt.mappingException("Can not support implicit polymorphic deserialization for POJOs-as-Arrays style: " +"nominal type "+_beanType.getRawClass().getName()+", actual type "+bean.getClass().getName()); } } continue; } // Object Id property? if (buffer.readIdProperty(propName)) { continue; } // regular property? needs buffering buffer.bufferProperty(prop, prop.

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>deserialize(jp, ctxt)); } // In case we didn't quite get all the creator properties, we may have to do this: if (bean == null) { try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); return null; // never gets here } } return bean; } /* /********************************************************** /* Helper methods, error reporting /********************************************************** */ protected Object _deserializeFromNonArray(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // Let's start with failure throw ctxt.mappingException("Can not deserialize a POJO (of type "+_beanType.getRawClass().getName() +") from non-Array representation (token: "+jp.getCurrentToken() +"): type/property designed to be serialized as JSON Array"); // in future, may allow use of "standard" POJO serialization as well; if so, do: //return _delegate.deserialize(jp, ctxt); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.IOException; import java.lang.reflect.Type; import java.text.DateFormat; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; /** * Compared to regular {@link java.util.Date} serialization, we do use String * representation here. Why? Basically to truncate of time part, since * that should not be used by plain SQL date. */ @JacksonStdImpl public class SqlDateSerializer extends DateTimeSerializerBase<java.sql.Date> { public SqlDateSerializer() { /* 12-Apr-2014, tatu: for now, pass explicit 'false' to mean 'not using timestamp', * for backwards compatibility; this differs from other Date/Calendar types. */ this(Boolean.FALSE); } protected SqlDateSerializer(Boolean useTimestamp) { super(java.sql.Date.class, useTimestamp, null); } @Override public SqlDateSerializer withFormat(Boolean timestamp, DateFormat customFormat) { return new SqlDateSerializer(timestamp); } @Override protected long _timestamp(java.sql.Date value) { return (value == null) ? 0L : value.getTime(); } @Override public void serialize(java.sql.Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { if (_useTimestamp) { jgen.writeNumber(_timestamp(value)); } else { jgen.writeString(value.toString()); } } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { //todo: (ryan) add a format for the date in the schema? return createSchemaNode("string", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { _acceptJsonFormatVisitor(visitor, type

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.IOException; import java.lang.reflect.Type; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; /** * Also: default bean access will not do much good with Class.class. But * we can just serialize the class name and that should be enough. */ public class ClassSerializer extends StdScalarSerializer<Class<?>> { public ClassSerializer() { super(Class.class, false); } @Override public void serialize(Class<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { jgen.writeString(value.getName()); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("string", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { visitor.expectStringFormat(typeHint); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>, null); } protected StdKeyDeserializer(int kind, Class<?> cls, FromStringDeserializer<?> deser) { _kind = kind; _keyClass = cls; _deser = deser; } public static StdKeyDeserializer forType(Class<?> raw) { int kind; // first common types: if (raw == String.class || raw == Object.class) { return StringKD.forType(raw); } else if (raw == UUID.class) { kind = TYPE_UUID; } else if (raw == Integer.class) { kind = TYPE_INT; } else if (raw == Long.class) { kind = TYPE_LONG; } else if (raw == Date.class) { kind = TYPE_DATE; } else if (raw == Calendar.class) { kind = TYPE_CALENDAR; // then less common ones... } else if (raw == Boolean.class) { kind = TYPE_BOOLEAN; } else if (raw == Byte.class) { kind = TYPE_BYTE; } else if (raw == Character.class) { kind = TYPE_CHAR; } else if (raw == Short.class) { kind = TYPE_SHORT; } else if (raw == Float.class) { kind = TYPE_FLOAT; } else if (raw == Double.class) { kind = TYPE_DOUBLE; } else if (raw == Locale.class) { FromStringDeserializer<?> deser = FromStringDeserializer.findDeserializer(Locale.class); return new StdKeyDeserializer(TYPE_LOCALE, raw, deser); } else { return null; } return new StdKeyDeserializer(kind, raw); } @Override public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (key == null) { // is this even legal call? return null; } try { Object result = _parse(key, ctxt); if (result != null) { return result; } } catch (Exception re) { throw ctxt.weirdKeyException(_keyClass, key, "not a valid representation: "+re.getMessage()); } if (_keyClass.isEnum() && ctxt.getConfig().

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) { return null; } throw ctxt.weirdKeyException(_keyClass, key, "not a valid representation"); } public Class<?> getKeyClass() { return _keyClass; } protected Object _parse(String key, DeserializationContext ctxt) throws Exception { switch (_kind) { case TYPE_BOOLEAN: if ("true".equals(key)) { return Boolean.TRUE; } if ("false".equals(key)) { return Boolean.FALSE; } throw ctxt.weirdKeyException(_keyClass, key, "value not 'true' or 'false'"); case TYPE_BYTE: { int value = _parseInt(key); // as per [JACKSON-804], allow range up to 255, inclusive if (value < Byte.MIN_VALUE || value > 255) { throw ctxt.weirdKeyException(_keyClass, key, "overflow, value can not be represented as 8-bit value"); } return Byte.valueOf((byte) value); } case TYPE_SHORT: { int value = _parseInt(key); if (value < Short.MIN_VALUE || value > Short.MAX_VALUE) { throw ctxt.weirdKeyException(_keyClass, key, "overflow, value can not be represented as 16-bit value"); } return Short.valueOf((short) value); } case TYPE_CHAR: if (key.length() == 1) { return Character.valueOf(key.charAt(0)); } throw ctxt.weirdKeyException(_keyClass, key, "can only convert 1-character Strings"); case TYPE_INT: return _parseInt(key); case TYPE_LONG: return _parseLong(key); case TYPE_FLOAT: /* 22-Jan-2009, tatu: Bounds/range checks would be tricky * here, so let's not bother even trying... */ return Float.valueOf((float) _parseDouble(key)); case TYPE_DOUBLE: return _parseDouble(key); case TYPE_LOCALE: try { return _deser._deserialize(key, ctxt);

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } catch (IOException e) { throw ctxt.weirdKeyException(_keyClass, key, "unable to parse key as locale"); } case TYPE_DATE: return ctxt.parseDate(key); case TYPE_CALENDAR: java.util.Date date = ctxt.parseDate(key); return (date == null) ? null : ctxt.constructCalendar(date); case TYPE_UUID: return UUID.fromString(key); } return null; } /* /********************************************************** /* Helper methods for sub-classes /********************************************************** */ protected int _parseInt(String key) throws IllegalArgumentException { return Integer.parseInt(key); } protected long _parseLong(String key) throws IllegalArgumentException { return Long.parseLong(key); } protected double _parseDouble(String key) throws IllegalArgumentException { return NumberInput.parseDouble(key); } /* /********************************************************** /* First: the standard "String as String" deserializer /********************************************************** */ @JacksonStdImpl final static class StringKD extends StdKeyDeserializer { private static final long serialVersionUID = 1L; private final static StringKD sString = new StringKD(String.class); private final static StringKD sObject = new StringKD(Object.class); private StringKD(Class<?> nominalType) { super(-1, nominalType); } public static StringKD forType(Class<?> nominalType) { if (nominalType == String.class) { return sString; } if (nominalType == Object.class) { return sObject; } return new StringKD(nominalType); } @Override public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException { return key; } } /* /********************************************************** /* Key deserializer implementations; other /********************************************************** */ /** * Key deserializer that wraps a "regular" deserializer (but one * that must recognize FIELD_NAMEs as text!) to reuse existing * handlers as key handlers. */ final static class DelegatingKD extends KeyDeserializer // note: NOT the std one implements java.io.Serializable { private static final long serialVersionUID = 1L; final protected Class<?> _keyClass;

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> protected final JsonDeserializer<?> _delegate; protected DelegatingKD(Class<?> cls, JsonDeserializer<?> deser) { _keyClass = cls; _delegate = deser; } @Override public final Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (key == null) { // is this even legal call? return null; } try { // Ugh... should not have to give parser which may or may not be correct one... Object result = _delegate.deserialize(ctxt.getParser(), ctxt); if (result != null) { return result; } } catch (Exception re) { throw ctxt.weirdKeyException(_keyClass, key, "not a valid representation: "+re.getMessage()); } throw ctxt.weirdKeyException(_keyClass, key, "not a valid representation"); } public Class<?> getKeyClass() { return _keyClass; } } @JacksonStdImpl final static class EnumKD extends StdKeyDeserializer { private static final long serialVersionUID = 1L; protected final EnumResolver<?> _resolver; protected final AnnotatedMethod _factory; protected EnumKD(EnumResolver<?> er, AnnotatedMethod factory) { super(-1, er.getEnumClass()); _resolver = er; _factory = factory; } @Override public Object _parse(String key, DeserializationContext ctxt) throws JsonMappingException { if (_factory != null) { try { return _factory.call1(key); } catch (Exception e) { ClassUtil.unwrapAndThrowAsIAE(e); } } Enum<?> e = _resolver.findEnum(key); if (e == null && !ctxt.getConfig().isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) { throw ctxt.weirdKeyException(_keyClass, key, "not one of values for Enum class"); } return e; } } /** * Key deserializer that calls a single-string-arg constructor * to instantiate desired key type. */ final static class StringCtorKeyDeserializer extends StdKeyDeserializer { private static final long serialVersionUID = 1L; protected final Constructor<?> _ctor; public StringCtor

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>KeyDeserializer(Constructor<?> ctor) { super(-1, ctor.getDeclaringClass()); _ctor = ctor; } @Override public Object _parse(String key, DeserializationContext ctxt) throws Exception { return _ctor.newInstance(key); } } /** * Key deserializer that calls a static no-args factory method * to instantiate desired key type. */ final static class StringFactoryKeyDeserializer extends StdKeyDeserializer { private static final long serialVersionUID = 1L; final Method _factoryMethod; public StringFactoryKeyDeserializer(Method fm) { super(-1, fm.getDeclaringClass()); _factoryMethod = fm; } @Override public Object _parse(String key, DeserializationContext ctxt) throws Exception { return _factoryMethod.invoke(null, key); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind; import java.io.IOException; import java.io.Serializable; import java.util.*; import com.fasterxml.jackson.core.*; /** * Checked exception used to signal fatal problems with mapping of * content. *<p> * One additional feature is the ability to denote relevant path * of references (during serialization/deserialization) to help in * troubleshooting. */ public class JsonMappingException extends JsonProcessingException { private static final long serialVersionUID = 1L; /** * Let's limit length of reference chain, to limit damage in cases * of infinite recursion. */ final static int MAX_REFS_TO_LIST = 1000; /* /********************************************************** /* Helper classes /********************************************************** */ /** * Simple bean class used to contain references. References * can be added to indicate execution/reference path that * lead to the problem that caused this exception to be * thrown. */ public static class Reference implements Serializable { private static final long serialVersionUID = 1L; /** * Object through which reference was resolved. Can be either * actual instance (usually the case for serialization), or * Class (usually the case for deserialization). */ protected Object _from; /** * Name of field (for beans) or key (for Maps) that is part * of the reference. May be null for Collection types (which * generally have {@link #_index} defined), or when resolving * Map classes without (yet) having an instance to operate on. */ protected String _fieldName; /** * Index within a {@link Collection} instance that contained * the reference; used if index is relevant and available. * If either not applicable, or not available, -1 is used to * denote "not known". */ protected int _index = -1; /** * Default constructor for deserialization/sub-classing purposes */ protected Reference() { } public Reference(Object from) { _from = from; } public Reference(Object from, String fieldName) { _from = from; if (fieldName == null) { throw new NullPointerException("Can not pass null fieldName"); } _fieldName = fieldName; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> public Reference(Object from, int index) { _from = from; _index = index; } public void setFrom(Object o) { _from = o; } public void setFieldName(String n) { _fieldName = n; } public void setIndex(int ix) { _index = ix; } public Object getFrom() { return _from; } public String getFieldName() { return _fieldName; } public int getIndex() { return _index; } @Override public String toString() { StringBuilder sb = new StringBuilder(); Class<?> cls = (_from instanceof Class<?>) ? ((Class<?>)_from) : _from.getClass(); /* Hmmh. Although Class.getName() is mostly ok, it does look * butt-ugly for arrays. So let's use getSimpleName() instead; * but have to prepend package name too. */ Package pkg = cls.getPackage(); if (pkg != null) { sb.append(pkg.getName()); sb.append('.'); } sb.append(cls.getSimpleName()); sb.append('['); if (_fieldName != null) { sb.append('"'); sb.append(_fieldName); sb.append('"'); } else if (_index >= 0) { sb.append(_index); } else { sb.append('?'); } sb.append(']'); return sb.toString(); } } /* /********************************************************** /* State/configuration /********************************************************** */ /** * Path through which problem that triggering throwing of * this exception was reached. */ protected LinkedList<Reference> _path; /* /********************************************************** /* Life-cycle /********************************************************** */ public JsonMappingException(String msg) { super(msg); } public JsonMappingException(String msg, Throwable rootCause) { super(msg, rootCause); } public JsonMappingException(String msg, JsonLocation loc) { super(msg, loc); } public JsonMappingException(String msg, JsonLocation loc, Throwable rootCause) { super(msg, loc, rootCause); } public static JsonMappingException from(JsonParser jp, String msg) { return new JsonMappingException(msg, ((jp == null) ? null : jp.getTokenLocation()));

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } public static JsonMappingException from(JsonParser jp, String msg, Throwable problem) { return new JsonMappingException(msg, ((jp == null) ? null : jp.getTokenLocation()), problem); } /** * Factory method used when "upgrading" an {@link IOException} into * {@link JsonMappingException}: usually only needed to comply with * a signature. * * @since 2.1 */ public static JsonMappingException fromUnexpectedIOE(IOException src) { return new JsonMappingException("Unexpected IOException (of type " +src.getClass().getName()+"): "+src.getMessage(), (JsonLocation)null, src); } /** * Method that can be called to either create a new JsonMappingException * (if underlying exception is not a JsonMappingException), or augment * given exception with given path/reference information. * * This version of method is called when the reference is through a * non-indexed object, such as a Map or POJO/bean. */ public static JsonMappingException wrapWithPath(Throwable src, Object refFrom, String refFieldName) { return wrapWithPath(src, new Reference(refFrom, refFieldName)); } /** * Method that can be called to either create a new JsonMappingException * (if underlying exception is not a JsonMappingException), or augment * given exception with given path/reference information. * * This version of method is called when the reference is through an * index, which happens with arrays and Collections. */ public static JsonMappingException wrapWithPath(Throwable src, Object refFrom, int index) { return wrapWithPath(src, new Reference(refFrom, index)); } /** * Method that can be called to either create a new JsonMappingException * (if underlying exception is not a JsonMappingException), or augment * given exception with given path/reference information. */ public static JsonMappingException wrapWithPath(Throwable src, Reference ref) { JsonMappingException jme; if (src instanceof JsonMappingException) { jme = (JsonMappingException) src; } else { String msg = src.getMessage(); /* Related to [JACKSON-62], let's use a more meaningful placeholder * if all we have is

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> null */ if (msg == null || msg.length() == 0) { msg = "(was "+src.getClass().getName()+")"; } jme = new JsonMappingException(msg, null, src); } jme.prependPath(ref); return jme; } /* /********************************************************** /* Accessors/mutators /********************************************************** */ /** * Method for accessing full structural path within type hierarchy * down to problematic property. */ public List<Reference> getPath() { if (_path == null) { return Collections.emptyList(); } return Collections.unmodifiableList(_path); } /** * Method for accesing description of path that lead to the * problem that triggered this exception */ public String getPathReference() { return getPathReference(new StringBuilder()).toString(); } public StringBuilder getPathReference(StringBuilder sb) { _appendPathDesc(sb); return sb; } /** * Method called to prepend a reference information in front of * current path */ public void prependPath(Object referrer, String fieldName) { Reference ref = new Reference(referrer, fieldName); prependPath(ref); } /** * Method called to prepend a reference information in front of * current path */ public void prependPath(Object referrer, int index) { Reference ref = new Reference(referrer, index); prependPath(ref); } public void prependPath(Reference r) { if (_path == null) { _path = new LinkedList<Reference>(); } /* Also: let's not increase without bounds. Could choose either * head or tail; tail is easier (no need to ever remove), as * well as potentially more useful so let's use it: */ if (_path.size() < MAX_REFS_TO_LIST) { _path.addFirst(r); } } /* /********************************************************** /* Overridden methods /********************************************************** */ @Override public String getLocalizedMessage() { return _buildMessage(); } /** * Method is overridden so that we can properly inject description * of problem path, if such is defined. */ @Override public String getMessage() { return _buildMessage();

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>JavaType valueType, boolean staticTyping, EnumValues keyEnums, TypeSerializer vts, JsonSerializer<Object> valueSerializer) { super(EnumMap.class, false); _property = null; // not yet known _staticTyping = staticTyping || (valueType != null && valueType.isFinal()); _valueType = valueType; _keyEnums = keyEnums; _valueTypeSerializer = vts; _valueSerializer = valueSerializer; } /** * Constructor called when a contextual instance is created. */ @SuppressWarnings("unchecked") public EnumMapSerializer(EnumMapSerializer src, BeanProperty property, JsonSerializer<?> ser) { super(src); _property = property; _staticTyping = src._staticTyping; _valueType = src._valueType; _keyEnums = src._keyEnums; _valueTypeSerializer = src._valueTypeSerializer; _valueSerializer = (JsonSerializer<Object>) ser; } @Override public EnumMapSerializer _withValueTypeSerializer(TypeSerializer vts) { return new EnumMapSerializer(_valueType, _staticTyping, _keyEnums, vts, _valueSerializer); } public EnumMapSerializer withValueSerializer(BeanProperty prop, JsonSerializer<?> ser) { if (_property == prop && ser == _valueSerializer) { return this; } return new EnumMapSerializer(this, prop, ser); } @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { /* 29-Sep-2012, tatu: Actually, we need to do much more contextual * checking here since we finally know for sure the property, * and it may have overrides */ JsonSerializer<?> ser = null; // First: if we have a property, may have property-annotation overrides if (property != null) { AnnotatedMember m = property.getMember(); if (m != null) { Object serDef = provider.getAnnotationIntrospector().findContentSerializer(m); if (serDef != null) { ser = provider.serializerInstance(m, serDef); } } } if (ser == null) { ser = _valueSerializer; } // #124: May have a content

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>SerializationFeature.WRITE_NULL_MAP_VALUES); final TypeSerializer vts = _valueTypeSerializer; for (Map.Entry<? extends Enum<?>,?> entry : value.entrySet()) { final Object valueElem = entry.getValue(); if (skipNulls && valueElem == null) { // [JACKSON-314] skip entries with null values? continue; } // First, serialize key Enum<?> key = entry.getKey(); if (keyEnums == null) { /* 15-Oct-2009, tatu: This is clumsy, but still the simplest efficient * way to do it currently, as Serializers get cached. (it does assume we'll always use * default serializer tho -- so ideally code should be rewritten) */ // ... and lovely two-step casting process too... StdSerializer<?> ser = (StdSerializer<?>) provider.findValueSerializer( key.getDeclaringClass(), _property); keyEnums = ((EnumSerializer) ser).getEnumValues(); } jgen.writeFieldName(keyEnums.serializedValueFor(key)); if (valueElem == null) { provider.defaultSerializeNull(jgen); continue; } Class<?> cc = valueElem.getClass(); JsonSerializer<Object> currSerializer; if (cc == prevClass) { currSerializer = prevSerializer; } else { currSerializer = provider.findValueSerializer(cc, _property); prevSerializer = currSerializer; prevClass = cc; } try { if (vts == null) { currSerializer.serialize(valueElem, jgen, provider); } else { currSerializer.serializeWithType(valueElem, jgen, provider, vts); } } catch (Exception e) { // [JACKSON-55] Need to add reference information wrapAndThrow(provider, e, value, entry.getKey().name()); } } } protected void serializeContentsUsing(EnumMap<? extends Enum<?>,?> value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> valueSer) throws IOException, JsonGenerationException { EnumValues keyEnums = _keyEnums; final boolean skipNulls = !provider.isEnabled(SerializationFeature.WRITE_NULL

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>_MAP_VALUES); final TypeSerializer vts = _valueTypeSerializer; for (Map.Entry<? extends Enum<?>,?> entry : value.entrySet()) { final Object valueElem = entry.getValue(); if (skipNulls && valueElem == null) { // [JACKSON-314] skip entries with null values? continue; } Enum<?> key = entry.getKey(); if (keyEnums == null) { // clumsy, but has to do for now: StdSerializer<?> ser = (StdSerializer<?>) provider.findValueSerializer(key.getDeclaringClass(), _property); keyEnums = ((EnumSerializer) ser).getEnumValues(); } jgen.writeFieldName(keyEnums.serializedValueFor(key)); if (valueElem == null) { provider.defaultSerializeNull(jgen); continue; } try { if (vts == null) { valueSer.serialize(valueElem, jgen, provider); } else { valueSer.serializeWithType(valueElem, jgen, provider, vts); } } catch (Exception e) { wrapAndThrow(provider, e, value, entry.getKey().name()); } } } @SuppressWarnings({ "unchecked", "deprecation" }) @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { ObjectNode o = createSchemaNode("object", true); if (typeHint instanceof ParameterizedType) { Type[] typeArgs = ((ParameterizedType) typeHint).getActualTypeArguments(); if (typeArgs.length == 2) { JavaType enumType = provider.constructType(typeArgs[0]); JavaType valueType = provider.constructType(typeArgs[1]); ObjectNode propsNode = JsonNodeFactory.instance.objectNode(); Class<Enum<?>> enumClass = (Class<Enum<?>>) enumType.getRawClass(); for (Enum<?> enumValue : enumClass.getEnumConstants()) { JsonSerializer<Object> ser = provider.findValueSerializer(valueType.getRawClass(), _property); JsonNode schemaNode = (ser instanceof SchemaAware) ? ((SchemaAware) ser).getSchema(provider, null) : com.fasterxml.jackson.databind.jsonschema.JsonSchema.

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>getDefaultSchemaNode(); propsNode.put(provider.getConfig().getAnnotationIntrospector().findEnumValue((Enum<?>)enumValue), schemaNode); } o.put("properties", propsNode); } } return o; } /** * We consider possibility here that an EnumMap might actually just be serialized * as something like a Record, given that number of keys is bound, just like * with Objects/Records (and not unbounded like regular maps) */ @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { if (visitor == null) { return; } JsonObjectFormatVisitor objectVisitor = visitor.expectObjectFormat(typeHint); if (objectVisitor == null) { return; } JavaType valueType = typeHint.containedType(1); JsonSerializer<Object> ser = _valueSerializer; if (ser == null && valueType != null) { ser = visitor.getProvider().findValueSerializer(valueType, _property); } if (valueType == null) { valueType = visitor.getProvider().constructType(Object.class); } EnumValues keyEnums = _keyEnums; if (keyEnums == null) { JavaType enumType = typeHint.containedType(0); if (enumType == null) { throw new IllegalStateException("Can not resolve Enum type of EnumMap: "+typeHint); } JsonSerializer<?> enumSer = visitor.getProvider().findValueSerializer(enumType, _property); if (!(enumSer instanceof EnumSerializer)) { throw new IllegalStateException("Can not resolve Enum type of EnumMap: "+typeHint); } keyEnums = ((EnumSerializer) enumSer).getEnumValues(); } for (Map.Entry<?,SerializableString> entry : keyEnums.internalMap().entrySet()) { String name = entry.getValue().getValue(); // should all have the same type, so: if (ser == null) { ser = visitor.getProvider().findValueSerializer(entry.getKey().getClass(), _property); } objectVisitor.property(name, (JsonFormatVisitable) ser, valueType); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> * Method called to check whether given serializable value is * considered "empty" value (for purposes of suppressing serialization * of empty values). *<p> * Default implementation will consider only null values to be empty. * * @since 2.0 */ public boolean isEmpty(T value) { return (value == null); } /** * Method that can be called to see whether this serializer instance * will use Object Id to handle cyclic references. */ public boolean usesObjectId() { return false; } /** * Accessor for checking whether this serializer is an * "unwrapping" serializer; this is necessary to know since * it may also require caller to suppress writing of the * leading property name. */ public boolean isUnwrappingSerializer() { return false; } /** * Accessor that can be used to determine if this serializer uses * another serializer for actual serialization, by delegating * calls. If so, will return immediate delegate (which itself may * delegate to further serializers); otherwise will return null. * * @return Serializer this serializer delegates calls to, if null; * null otherwise. * * @since 2.1 */ public JsonSerializer<?> getDelegatee() { return null; } /* /********************************************************** /* Default JsonFormatVisitable implementation /********************************************************** */ /** * Default implementation simply calls {@link JsonFormatVisitorWrapper#expectAnyFormat(JavaType)}. * * @since 2.1 */ @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException { if (visitor != null) visitor.expectAnyFormat(type); } /* /********************************************************** /* Helper class(es) /********************************************************** */ /** * This marker class is only to be used with annotations, to * indicate that <b>no serializer is configured</b>. *<p> * Specifically, this class is to be used as the marker for * annotation {@link com.fasterxml.jackson.databind.annotation.JsonSerialize}. */ public abstract static class None extends JsonSerializer<Object> { } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.IOException; import java.lang.reflect.Type; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; import com.fasterxml.jackson.databind.jsontype.TypeSerializer; public abstract class StdScalarSerializer<T> extends StdSerializer<T> { protected StdScalarSerializer(Class<T> t) { super(t); } /** * Alternate constructor that is (alas!) needed to work * around kinks of generic type handling */ @SuppressWarnings("unchecked") protected StdScalarSerializer(Class<?> t, boolean dummy) { super((Class<T>) t); } /** * Default implementation will write type prefix, call regular serialization * method (since assumption is that value itself does not need JSON * Array or Object start/end markers), and then write type suffix. * This should work for most cases; some sub-classes may want to * change this behavior. */ @Override public void serializeWithType(T value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonGenerationException { typeSer.writeTypePrefixForScalar(value, jgen); serialize(value, jgen, provider); typeSer.writeTypeSuffixForScalar(value, jgen); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { return createSchemaNode("string", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { if (visitor != null) { // 13-Sep-2013, tatu: Let's assume it's usually a String, right? // visitor.expectAnyFormat(typeHint); visitor.expectStringFormat(typeHint); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonMappingException; /** * Interface used to indicate deserializers that want to do post-processing * after construction but before being returned to caller (and possibly cached) * and used. * This is typically used to resolve references * to other contained types; for example, bean deserializers use this callback * to locate deserializers for contained field types. * Main reason for using a callback (instead of trying to resolve dependencies * immediately) is to make it possible to cleanly handle self-references; * otherwise it would be easy to get into infinite recursion. *<p> * Note that {@link #resolve} method does NOT allow returning anything * (specifically, a new deserializer instance): reason for this is that * allowing this would not work with proper handling of cyclic dependencies, * which are resolved by two-phase processing, where initially constructed * deserializer is added as known deserializer, and only after this * resolution is done. Resolution is the part that results in lookups for * dependant deserializers, which may include handling references to * deserializer itself. *<p> * Note that in cases where deserializer needs both contextualization and * resolution -- that is, implements both this interface and {@link ContextualDeserializer} * -- resolution via this interface occurs first, and contextual * resolution (using {@link ContextualDeserializer}) later on. */ public interface ResolvableDeserializer { /** * Method called after deserializer instance has been constructed * (and registered as necessary by provider objects), * but before it has returned it to the caller. * Called object can then resolve its dependencies to other types, * including self-references (direct or indirect). * * @param ctxt Context to use for accessing configuration, resolving * secondary deserializers */ public abstract void resolve(DeserializationContext ctxt) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> serializeContentsUsing(value, jgen, provider, _elementSerializer); return; } if (_valueTypeSerializer != null) { serializeTypedContents(value, jgen, provider); return; } final int len = value.size(); if (len == 0) { return; } int i = 0; try { PropertySerializerMap serializers = _dynamicSerializers; for (; i < len; ++i) { Object elem = value.get(i); if (elem == null) { provider.defaultSerializeNull(jgen); } else { Class<?> cc = elem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { // To fix [JACKSON-508] if (_elementType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_elementType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicSerializers; } serializer.serialize(elem, jgen, provider); } } } catch (Exception e) { // [JACKSON-55] Need to add reference information wrapAndThrow(provider, e, value, i); } } public void serializeContentsUsing(List<?> value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException, JsonGenerationException { final int len = value.size(); if (len == 0) { return; } final TypeSerializer typeSer = _valueTypeSerializer; for (int i = 0; i < len; ++i) { Object elem = value.get(i); try { if (elem == null) { provider.defaultSerializeNull(jgen); } else if (typeSer == null) { ser.serialize(elem, jgen, provider); } else { ser.serializeWithType(elem, jgen, provider, typeSer); } } catch (Exception e) { // [JACKSON-55] Need to add reference information wrapAndThrow(provider, e, value, i); } } } public void serializeTyped

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Contents(List<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { final int len = value.size(); if (len == 0) { return; } int i = 0; try { final TypeSerializer typeSer = _valueTypeSerializer; PropertySerializerMap serializers = _dynamicSerializers; for (; i < len; ++i) { Object elem = value.get(i); if (elem == null) { provider.defaultSerializeNull(jgen); } else { Class<?> cc = elem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { // To fix [JACKSON-508] if (_elementType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_elementType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicSerializers; } serializer.serializeWithType(elem, jgen, provider, typeSer); } } } catch (Exception e) { // [JACKSON-55] Need to add reference information wrapAndThrow(provider, e, value, i); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> /** * Method that will introspect subset of bean properties needed to * construct bean instance. */ @SuppressWarnings("unchecked") public <T extends BeanDescription> T introspectForCreation(JavaType type) { return (T) getClassIntrospector().forCreation(this, type, this); } /** * @since 2.0 */ @SuppressWarnings("unchecked") public <T extends BeanDescription> T introspectForBuilder(JavaType type) { return (T) getClassIntrospector().forDeserializationWithBuilder(this, type, this); } /* /********************************************************** /* Support for polymorphic type handling /********************************************************** */ /** * Helper method that is needed to properly handle polymorphic referenced * types, such as types referenced by {@link java.util.concurrent.atomic.AtomicReference}, * or various "optional" types. * * @since 2.4 */ public TypeDeserializer findTypeDeserializer(JavaType baseType) throws JsonMappingException { BeanDescription bean = introspectClassAnnotations(baseType.getRawClass()); AnnotatedClass ac = bean.getClassInfo(); TypeResolverBuilder<?> b = getAnnotationIntrospector().findTypeResolver(this, ac, baseType); /* Ok: if there is no explicit type info handler, we may want to * use a default. If so, config object knows what to use. */ Collection<NamedType> subtypes = null; if (b == null) { b = getDefaultTyper(baseType); if (b == null) { return null; } } else { subtypes = getSubtypeResolver().collectAndResolveSubtypes(ac, this, getAnnotationIntrospector()); } /* 04-May-2014, tatu: When called from DeserializerFactory, additional code like * this is invoked. But here we do not actually have access to mappings, so not * quite sure what to do, if anything. May need to revisit if the underlying * problem re-surfaces... */ /* if ((b.getDefaultImpl() == null) && baseType.isAbstract()) { JavaType defaultType = mapAbstractType(config, baseType); if (defaultType != null && defaultType.

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> /* Serialization /********************************************************** */ @Override public abstract void serialize(T value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException; /* /********************************************************** /* Helper methods for JSON Schema generation /********************************************************** */ /** * Default implementation simply claims type is "string"; usually * overriden by custom serializers. */ @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { return createSchemaNode("string"); } /** * Default implementation simply claims type is "string"; usually * overriden by custom serializers. */ @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint, boolean isOptional) throws JsonMappingException { ObjectNode schema = (ObjectNode) getSchema(provider, typeHint); if (!isOptional) { schema.put("required", !isOptional); } return schema; } protected ObjectNode createObjectNode() { return JsonNodeFactory.instance.objectNode(); } protected ObjectNode createSchemaNode(String type) { ObjectNode schema = createObjectNode(); schema.put("type", type); return schema; } protected ObjectNode createSchemaNode(String type, boolean isOptional) { ObjectNode schema = createSchemaNode(type); // as per [JACKSON-563]. Note that 'required' defaults to false if (!isOptional) { schema.put("required", !isOptional); } return schema; } /** * Default implementation specifies no format. This behavior is usually * overriden by custom serializers. */ @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { visitor.expectAnyFormat(typeHint); } /* /********************************************************** /* Helper methods for exception handling /********************************************************** */ /** * Method that will modify caught exception (passed in as argument) * as necessary to include reference information, and to ensure it * is a subtype of {@link IOException}, or an unchecked exception. *<p> * Rules for wrapping and unwrapping are bit complicated; essentially: *<ul> * <li>Errors are

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> to be passed as is (if uncovered via unwrapping) * <li>"Plain" IOExceptions (ones that are not of type * {@link JsonMappingException} are to be passed as is *</ul> */ public void wrapAndThrow(SerializerProvider provider, Throwable t, Object bean, String fieldName) throws IOException { /* 05-Mar-2009, tatu: But one nasty edge is when we get * StackOverflow: usually due to infinite loop. But that * usually gets hidden within an InvocationTargetException... */ while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } // Errors and "plain" IOExceptions to be passed as is if (t instanceof Error) { throw (Error) t; } // Ditto for IOExceptions... except for mapping exceptions! boolean wrap = (provider == null) || provider.isEnabled(SerializationFeature.WRAP_EXCEPTIONS); if (t instanceof IOException) { if (!wrap || !(t instanceof JsonMappingException)) { throw (IOException) t; } } else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions if (t instanceof RuntimeException) { throw (RuntimeException) t; } } // [JACKSON-55] Need to add reference information throw JsonMappingException.wrapWithPath(t, bean, fieldName); } public void wrapAndThrow(SerializerProvider provider, Throwable t, Object bean, int index) throws IOException { while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } // Errors are to be passed as is if (t instanceof Error) { throw (Error) t; } // Ditto for IOExceptions... except for mapping exceptions! boolean wrap = (provider == null) || provider.isEnabled(SerializationFeature.WRAP_EXCEPTIONS); if (t instanceof IOException) { if (!wrap || !(t instanceof JsonMappingException)) { throw (IOException) t; } } else if (!wrap) { // [JACKSON-407] -- allow disabling wrapping for unchecked exceptions if (t instanceof RuntimeException) { throw

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> (RuntimeException) t; } } // [JACKSON-55] Need to add reference information throw JsonMappingException.wrapWithPath(t, bean, index); } /* /********************************************************** /* Helper methods, other /********************************************************** */ /** * Method that can be called to determine if given serializer is the default * serializer Jackson uses; as opposed to a custom serializer installed by * a module or calling application. Determination is done using * {@link JacksonStdImpl} annotation on serializer class. */ protected boolean isDefaultSerializer(JsonSerializer<?> serializer) { return ClassUtil.isJacksonStdImpl(serializer); } /** * Helper method that can be used to see if specified property has annotation * indicating that a converter is to be used for contained values (contents * of structured types; array/List/Map values) * * @param existingSerializer (optional) configured content * serializer if one already exists. * * @since 2.2 */ protected JsonSerializer<?> findConvertingContentSerializer(SerializerProvider provider, BeanProperty prop, JsonSerializer<?> existingSerializer) throws JsonMappingException { final AnnotationIntrospector intr = provider.getAnnotationIntrospector(); if (intr != null && prop != null) { Object convDef = intr.findSerializationContentConverter(prop.getMember()); if (convDef != null) { Converter<Object,Object> conv = provider.converterInstance(prop.getMember(), convDef); JavaType delegateType = conv.getOutputType(provider.getTypeFactory()); if (existingSerializer == null) { existingSerializer = provider.findValueSerializer(delegateType, prop); } return new StdDelegatingSerializer(conv, delegateType, existingSerializer); } } return existingSerializer; } /** * Helper method used to locate filter that is needed, based on filter id * this serializer was constructed with. * * @since 2.3 */ protected PropertyFilter findPropertyFilter(SerializerProvider provider, Object filterId, Object valueToFilter) throws JsonMappingException { FilterProvider filters = provider.getFilterProvider(); // Not ok to miss the provider, if a filter is declared to be needed. if (filters == null) { throw new

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> JsonMappingException("Can not resolve PropertyFilter with id '"+filterId+"'; no FilterProvider configured"); } PropertyFilter filter = filters.findPropertyFilter(filterId, valueToFilter); // But whether unknown ids are ok just depends on filter provider; if we get null that's fine return filter; } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> instances, where we do not yet know * which property is using this deserializer. */ public CollectionDeserializer(JavaType collectionType, JsonDeserializer<Object> valueDeser, TypeDeserializer valueTypeDeser, ValueInstantiator valueInstantiator) { this(collectionType, valueDeser, valueTypeDeser, valueInstantiator, null); } /** * Constructor used when creating contextualized instances. */ protected CollectionDeserializer(JavaType collectionType, JsonDeserializer<Object> valueDeser, TypeDeserializer valueTypeDeser, ValueInstantiator valueInstantiator, JsonDeserializer<Object> delegateDeser) { super(collectionType); _collectionType = collectionType; _valueDeserializer = valueDeser; _valueTypeDeserializer = valueTypeDeser; _valueInstantiator = valueInstantiator; _delegateDeserializer = delegateDeser; } /** * Copy-constructor that can be used by sub-classes to allow * copy-on-write styling copying of settings of an existing instance. */ protected CollectionDeserializer(CollectionDeserializer src) { super(src._collectionType); _collectionType = src._collectionType; _valueDeserializer = src._valueDeserializer; _valueTypeDeserializer = src._valueTypeDeserializer; _valueInstantiator = src._valueInstantiator; _delegateDeserializer = src._delegateDeserializer; } /** * Fluent-factory method call to construct contextual instance. */ @SuppressWarnings("unchecked") protected CollectionDeserializer withResolved(JsonDeserializer<?> dd, JsonDeserializer<?> vd, TypeDeserializer vtd) { if ((dd == _delegateDeserializer) && (vd == _valueDeserializer) && (vtd == _valueTypeDeserializer)) { return this; } return new CollectionDeserializer(_collectionType, (JsonDeserializer<Object>) vd, vtd, _valueInstantiator, (JsonDeserializer<Object>) dd); } /* /********************************************************** /* Validation, post-processing (ResolvableDeserializer) /********************************************************** */ /** * Method called to finalize setup of this deserializer, * when it is known for which property deserializer is needed * for. */ @Override public CollectionDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { // May need

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> be ok; bit tricky to check, however, since * there is also possibility of "auto-wrapping" of single-element arrays. * Hence we only accept empty String here. */ if (jp.getCurrentToken() == JsonToken.VALUE_STRING) { String str = jp.getText(); if (str.length() == 0) { return (Collection<Object>) _valueInstantiator.createFromString(ctxt, str); } } return deserialize(jp, ctxt, (Collection<Object>) _valueInstantiator.createUsingDefault(ctxt)); } @Override public Collection<Object> deserialize(JsonParser jp, DeserializationContext ctxt, Collection<Object> result) throws IOException, JsonProcessingException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt, result); } JsonDeserializer<Object> valueDes = _valueDeserializer; final TypeDeserializer typeDeser = _valueTypeDeserializer; CollectionReferringAccumulator referringAccumulator = (valueDes.getObjectIdReader() == null) ? null : new CollectionReferringAccumulator(_collectionType.getContentType().getRawClass(), result); JsonToken t; while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { try { Object value; if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(); } else if (typeDeser == null) { value = valueDes.deserialize(jp, ctxt); } else { value = valueDes.deserializeWithType(jp, ctxt, typeDeser); } if (referringAccumulator != null) { referringAccumulator.add(value); } else { result.add(value); } } catch (UnresolvedForwardReference reference) { if (referringAccumulator == null) { throw JsonMappingException .from(jp, "Unresolved forward reference but no identity info.", reference); } Referring ref = referringAccumulator.handleUnresolvedReference(reference); reference.getRoid().appendReferring(ref); } catch (Exception e) { // note: pass Object.class, not Object[].class, as we need element type for error info throw JsonMappingException

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>.wrapWithPath(e, Object.class, result.size()); } } return result; } @Override public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException, JsonProcessingException { // In future could check current token... for now this should be enough: return typeDeserializer.deserializeTypedFromArray(jp, ctxt); } /** * Helper method called when current token is no START_ARRAY. Will either * throw an exception, or try to handle value as if member of implicit * array, depending on configuration. */ protected final Collection<Object> handleNonArray(JsonParser jp, DeserializationContext ctxt, Collection<Object> result) throws IOException, JsonProcessingException { // [JACKSON-526]: implicit arrays from single values? if (!ctxt.isEnabled(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)) { throw ctxt.mappingException(_collectionType.getRawClass()); } JsonDeserializer<Object> valueDes = _valueDeserializer; final TypeDeserializer typeDeser = _valueTypeDeserializer; JsonToken t = jp.getCurrentToken(); Object value; try { if (t == JsonToken.VALUE_NULL) { value = valueDes.getNullValue(); } else if (typeDeser == null) { value = valueDes.deserialize(jp, ctxt); } else { value = valueDes.deserializeWithType(jp, ctxt, typeDeser); } } catch (Exception e) { // note: pass Object.class, not Object[].class, as we need element type for error info throw JsonMappingException.wrapWithPath(e, Object.class, result.size()); } result.add(value); return result; } public final static class CollectionReferringAccumulator { private final Class<?> _elementType; private final Collection<Object> _result; /** * A list of {@link CollectionReferring} to maintain ordering. */ private List<CollectionReferring> _accumulator = new ArrayList<CollectionReferring>(); public CollectionReferringAccumulator(Class<?> elementType, Collection<Object> result) { _elementType = elementType; _result = result; } public void add(Object value) {

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> classes and * interfaces, to avoid having to use exact types or annotations in * cases where the most common concrete Maps will do. */ @SuppressWarnings("rawtypes") final static HashMap<String, Class<? extends Map>> _mapFallbacks = new HashMap<String, Class<? extends Map>>(); static { _mapFallbacks.put(Map.class.getName(), LinkedHashMap.class); _mapFallbacks.put(ConcurrentMap.class.getName(), ConcurrentHashMap.class); _mapFallbacks.put(SortedMap.class.getName(), TreeMap.class); /* 11-Jan-2009, tatu: Let's see if we can still add support for * JDK 1.6 interfaces, even if we run on 1.5. Just need to be * more careful with typos, since compiler won't notice any * problems... */ _mapFallbacks.put("java.util.NavigableMap", TreeMap.class); try { Class<?> key = java.util.concurrent.ConcurrentNavigableMap.class; Class<?> value = java.util.concurrent.ConcurrentSkipListMap.class; @SuppressWarnings("unchecked") Class<? extends Map<?,?>> mapValue = (Class<? extends Map<?,?>>) value; _mapFallbacks.put(key.getName(), mapValue); } catch (Throwable e) { // some class loading problems are Errors, others Exceptions System.err.println("Problems with (optional) types: "+e); } } /* We do some defaulting for abstract Collection classes and * interfaces, to avoid having to use exact types or annotations in * cases where the most common concrete Collection will do. */ @SuppressWarnings("rawtypes") final static HashMap<String, Class<? extends Collection>> _collectionFallbacks = new HashMap<String, Class<? extends Collection>>(); static { _collectionFallbacks.put(Collection.class.getName(), ArrayList.class); _collectionFallbacks.put(List.class.getName(), ArrayList.class); _collectionFallbacks.put(Set.class.getName(), HashSet.class); _collectionFallbacks.put(SortedSet.class.getName(), TreeSet.class); _collectionFallbacks.put(Queue.class.getName(), LinkedList.class); //

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> new factory instance with additional * {@link AbstractTypeResolver}. */ @Override public final DeserializerFactory withAbstractTypeResolver(AbstractTypeResolver resolver) { return withConfig(_factoryConfig.withAbstractTypeResolver(resolver)); } /** * Convenience method for creating a new factory instance with additional * {@link ValueInstantiators}. */ @Override public final DeserializerFactory withValueInstantiators(ValueInstantiators instantiators) { return withConfig(_factoryConfig.withValueInstantiators(instantiators)); } /* /********************************************************** /* JsonDeserializerFactory impl (partial): type mappings /********************************************************** */ @Override public JavaType mapAbstractType(DeserializationConfig config, JavaType type) throws JsonMappingException { // first, general mappings while (true) { JavaType next = _mapAbstractType2(config, type); if (next == null) { return type; } /* Should not have to worry about cycles; but better verify since they will invariably * occur... :-) * (also: guard against invalid resolution to a non-related type) */ Class<?> prevCls = type.getRawClass(); Class<?> nextCls = next.getRawClass(); if ((prevCls == nextCls) || !prevCls.isAssignableFrom(nextCls)) { throw new IllegalArgumentException("Invalid abstract type resolution from "+type+" to "+next+": latter is not a subtype of former"); } type = next; } } /** * Method that will find abstract type mapping for specified type, doing a single * lookup through registered abstract type resolvers; will not do recursive lookups. */ private JavaType _mapAbstractType2(DeserializationConfig config, JavaType type) throws JsonMappingException { Class<?> currClass = type.getRawClass(); if (_factoryConfig.hasAbstractTypeResolvers()) { for (AbstractTypeResolver resolver : _factoryConfig.abstractTypeResolvers()) { JavaType concrete = resolver.findTypeMapping(config, type); if (concrete != null && concrete.getRawClass() != currClass) { return concrete; } } } return null; } /* /********************************************************** /* JsonDeserializerFactory impl (partial): ValueInstantiators /********************************************************** */ /** * Value instantiator is

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> created both based on creator annotations, * and on optional externally provided instantiators (registered through * module interface). */ @Override public ValueInstantiator findValueInstantiator(DeserializationContext ctxt, BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); ValueInstantiator instantiator = null; // [JACKSON-633] Check @JsonValueInstantiator before anything else AnnotatedClass ac = beanDesc.getClassInfo(); Object instDef = ctxt.getAnnotationIntrospector().findValueInstantiator(ac); if (instDef != null) { instantiator = _valueInstantiatorInstance(config, ac, instDef); } if (instantiator == null) { /* Second: see if some of standard Jackson/JDK types might provide value * instantiators. */ instantiator = _findStdValueInstantiator(config, beanDesc); if (instantiator == null) { instantiator = _constructDefaultValueInstantiator(ctxt, beanDesc); } } // finally: anyone want to modify ValueInstantiator? if (_factoryConfig.hasValueInstantiators()) { for (ValueInstantiators insts : _factoryConfig.valueInstantiators()) { instantiator = insts.findValueInstantiator(config, beanDesc, instantiator); // let's do sanity check; easier to spot buggy handlers if (instantiator == null) { throw new JsonMappingException("Broken registered ValueInstantiators (of type " +insts.getClass().getName()+"): returned null ValueInstantiator"); } } } // Sanity check: does the chosen instantatior have incomplete creators? if (instantiator.getIncompleteParameter() != null) { final AnnotatedParameter nonAnnotatedParam = instantiator.getIncompleteParameter(); final AnnotatedWithParams ctor = nonAnnotatedParam.getOwner(); throw new IllegalArgumentException("Argument #"+nonAnnotatedParam.getIndex()+" of constructor "+ctor+" has no property name annotation; must have name when multiple-parameter constructor annotated as Creator"); } return instantiator; } private ValueInstantiator _findStdValueInstantiator(DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { if (beanDesc.getBeanClass() == JsonLocation.class)

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> { return new JsonLocationInstantiator(); } return null; } /** * Method that will construct standard default {@link ValueInstantiator} * using annotations (like @JsonCreator) and visibility rules */ protected ValueInstantiator _constructDefaultValueInstantiator(DeserializationContext ctxt, BeanDescription beanDesc) throws JsonMappingException { boolean fixAccess = ctxt.canOverrideAccessModifiers(); CreatorCollector creators = new CreatorCollector(beanDesc, fixAccess); AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); // need to construct suitable visibility checker: final DeserializationConfig config = ctxt.getConfig(); VisibilityChecker<?> vchecker = config.getDefaultVisibilityChecker(); vchecker = intr.findAutoDetectVisibility(beanDesc.getClassInfo(), vchecker); /* Important: first add factory methods; then constructors, so * latter can override former! */ _addDeserializerFactoryMethods(ctxt, beanDesc, vchecker, intr, creators); // constructors only usable on concrete types: if (beanDesc.getType().isConcrete()) { _addDeserializerConstructors(ctxt, beanDesc, vchecker, intr, creators); } return creators.constructValueInstantiator(config); } public ValueInstantiator _valueInstantiatorInstance(DeserializationConfig config, Annotated annotated, Object instDef) throws JsonMappingException { if (instDef == null) { return null; } ValueInstantiator inst; if (instDef instanceof ValueInstantiator) { return (ValueInstantiator) instDef; } if (!(instDef instanceof Class)) { throw new IllegalStateException("AnnotationIntrospector returned key deserializer definition of type " +instDef.getClass().getName() +"; expected type KeyDeserializer or Class<KeyDeserializer> instead"); } Class<?> instClass = (Class<?>)instDef; if (ClassUtil.isBogusClass(instClass)) { return null; } if (!ValueInstantiator.class.isAssignableFrom(instClass)) { throw new IllegalStateException("AnnotationIntrospector returned Class "+instClass.getName() +"; expected Class<ValueInstantiator>"); } HandlerInstantiator hi = config.getHandlerInstantiator(); if (hi != null) { inst = hi.valueInstantiatorInstance(

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>config, annotated, instClass); if (inst != null) { return inst; } } return (ValueInstantiator) ClassUtil.createInstance(instClass, config.canOverrideAccessModifiers()); } protected void _addDeserializerConstructors (DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker, AnnotationIntrospector intr, CreatorCollector creators) throws JsonMappingException { /* First things first: the "default constructor" (zero-arg * constructor; whether implicit or explicit) is NOT included * in list of constructors, so needs to be handled separately. */ AnnotatedConstructor defaultCtor = beanDesc.findDefaultConstructor(); if (defaultCtor != null) { if (!creators.hasDefaultCreator() || intr.hasCreatorAnnotation(defaultCtor)) { creators.setDefaultCreator(defaultCtor); } } PropertyName[] ctorPropNames = null; AnnotatedConstructor propertyCtor = null; for (BeanPropertyDefinition propDef : beanDesc.findProperties()) { if (propDef.getConstructorParameter() != null) { AnnotatedParameter param = propDef.getConstructorParameter(); AnnotatedWithParams owner = param.getOwner(); if (owner instanceof AnnotatedConstructor) { if (propertyCtor == null) { propertyCtor = (AnnotatedConstructor) owner; ctorPropNames = new PropertyName[propertyCtor.getParameterCount()]; } ctorPropNames[param.getIndex()] = propDef.getFullName(); } } } for (AnnotatedConstructor ctor : beanDesc.getConstructors()) { int argCount = ctor.getParameterCount(); boolean isCreator = intr.hasCreatorAnnotation(ctor) || ctor == propertyCtor; boolean isVisible = vchecker.isCreatorVisible(ctor); // some single-arg constructors (String, number) are auto-detected if (argCount == 1) { PropertyName name = (ctor == propertyCtor) ? ctorPropNames[0] : null; _handleSingleArgumentConstructor(ctxt, beanDesc, vchecker, intr, creators, ctor, isCreator, isVisible, name); continue; } if (!isCreator && !isVisible) { continue; } // [JACKSON-541] improved handling a bit so:

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>-named) creators.addDelegatingCreator(ctor, properties); } else { // otherwise, record the incomplete parameter for later error messaging. creators.addIncompeteParameter(nonAnnotatedParam); } } } } protected boolean _handleSingleArgumentConstructor(DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker, AnnotationIntrospector intr, CreatorCollector creators, AnnotatedConstructor ctor, boolean isCreator, boolean isVisible, PropertyName name) throws JsonMappingException { // note: if we do have parameter name, it'll be "property constructor": AnnotatedParameter param = ctor.getParameter(0); if (name == null) { name = _findParamName(param, intr); } Object injectId = intr.findInjectableValueId(param); if ((injectId != null) || (name != null && name.hasSimpleName())) { // property-based // We know there's a name and it's only 1 parameter. CreatorProperty[] properties = new CreatorProperty[1]; properties[0] = constructCreatorProperty(ctxt, beanDesc, name, 0, param, injectId); creators.addPropertyCreator(ctor, properties); return true; } // otherwise either 'simple' number, String, or general delegate: Class<?> type = ctor.getRawParameterType(0); if (type == String.class) { if (isCreator || isVisible) { creators.addStringCreator(ctor); } return true; } if (type == int.class || type == Integer.class) { if (isCreator || isVisible) { creators.addIntCreator(ctor); } return true; } if (type == long.class || type == Long.class) { if (isCreator || isVisible) { creators.addLongCreator(ctor); } return true; } if (type == double.class || type == Double.class) { if (isCreator || isVisible) { creators.addDoubleCreator(ctor); } return true; } if (type == boolean.class || type == Boolean.class) { if (isCreator || isVisible) { creators.addBooleanCreator(ctor);

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } return true; } // Delegating Creator ok iff it has @JsonCreator (etc) if (isCreator) { creators.addDelegatingCreator(ctor, null); return true; } return false; } protected void _addDeserializerFactoryMethods (DeserializationContext ctxt, BeanDescription beanDesc, VisibilityChecker<?> vchecker, AnnotationIntrospector intr, CreatorCollector creators) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) { boolean isCreator = intr.hasCreatorAnnotation(factory); int argCount = factory.getParameterCount(); // zero-arg methods must be annotated; if so, are "default creators" [JACKSON-850] if (argCount == 0) { if (isCreator) { creators.setDefaultCreator(factory); } continue; } // some single-arg factory methods (String, number) are auto-detected if (argCount == 1) { AnnotatedParameter param = factory.getParameter(0); PropertyName pn = _findParamName(param, intr); String name = (pn == null) ? null : pn.getSimpleName(); Object injectId = intr.findInjectableValueId(param); if ((injectId == null) && (name == null || name.length() == 0)) { // not property based _handleSingleArgumentFactory(config, beanDesc, vchecker, intr, creators, factory, isCreator); // otherwise just ignored continue; } // fall through if there's name } else { // more than 2 args, must be @JsonCreator if (!intr.hasCreatorAnnotation(factory)) { continue; } } // 1 or more args; all params must have name annotations AnnotatedParameter nonAnnotatedParam = null; CreatorProperty[] properties = new CreatorProperty[argCount]; int namedCount = 0; int injectCount = 0; for (int i = 0; i < argCount; ++i) { AnnotatedParameter param = factory.getParameter(i); PropertyName name = _findParamName(param, intr); Object injectId = intr.findInjectableValueId(param); if

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> (name != null && name.hasSimpleName()) { ++namedCount; properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectId); } else if (injectId != null) { ++injectCount; properties[i] = constructCreatorProperty(ctxt, beanDesc, name, i, param, injectId); } else { NameTransformer unwrapper = intr.findUnwrappingNameTransformer(param); if (unwrapper != null) { properties[i] = constructCreatorProperty(ctxt, beanDesc, UNWRAPPED_CREATOR_PARAM_NAME, i, param, null); ++namedCount; } else { if (nonAnnotatedParam == null) { nonAnnotatedParam = param; } } } } // Ok: if named or injectable, we have more work to do if (isCreator || namedCount > 0 || injectCount > 0) { // simple case; everything covered: if ((namedCount + injectCount) == argCount) { creators.addPropertyCreator(factory, properties); } else if ((namedCount == 0) && ((injectCount + 1) == argCount)) { // [712] secondary: all but one injectable, one un-annotated (un-named) creators.addDelegatingCreator(factory, properties); } else { // otherwise, epic fail throw new IllegalArgumentException("Argument #"+nonAnnotatedParam.getIndex() +" of factory method "+factory+" has no property name annotation; must have name when multiple-parameter constructor annotated as Creator"); } } } } protected boolean _handleSingleArgumentFactory(DeserializationConfig config, BeanDescription beanDesc, VisibilityChecker<?> vchecker, AnnotationIntrospector intr, CreatorCollector creators, AnnotatedMethod factory, boolean isCreator) throws JsonMappingException { Class<?> type = factory.getRawParameterType(0); if (type == String.class) { if (isCreator || vchecker.isCreatorVisible(factory)) { creators.addStringCreator(factory); } return true; } if (type == int.class || type == Integer.class) { if (isCreator || vchecker.isCreatorVisible(factory)) { creators.add

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>IntCreator(factory); } return true; } if (type == long.class || type == Long.class) { if (isCreator || vchecker.isCreatorVisible(factory)) { creators.addLongCreator(factory); } return true; } if (type == double.class || type == Double.class) { if (isCreator || vchecker.isCreatorVisible(factory)) { creators.addDoubleCreator(factory); } return true; } if (type == boolean.class || type == Boolean.class) { if (isCreator || vchecker.isCreatorVisible(factory)) { creators.addBooleanCreator(factory); } return true; } if (intr.hasCreatorAnnotation(factory)) { creators.addDelegatingCreator(factory, null); return true; } return false; } /** * Method that will construct a property object that represents * a logical property passed via Creator (constructor or static * factory method) */ protected CreatorProperty constructCreatorProperty(DeserializationContext ctxt, BeanDescription beanDesc, PropertyName name, int index, AnnotatedParameter param, Object injectableValueId) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); final AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); PropertyMetadata metadata; { Boolean b = (intr == null) ? null : intr.hasRequiredMarker(param); boolean req = (b != null && b.booleanValue()); String desc = (intr == null) ? null : intr.findPropertyDescription(param); Integer idx = (intr == null) ? null : intr.findPropertyIndex(param); metadata = PropertyMetadata.construct(req, desc, idx); } JavaType t0 = config.getTypeFactory().constructType(param.getParameterType(), beanDesc.bindingsForBeanType()); BeanProperty.Std property = new BeanProperty.Std(name, t0, intr.findWrapperName(param), beanDesc.getClassAnnotations(), param, metadata); JavaType type = resolveType(ctxt, beanDesc, t0, param); if (type != t0) { property = property.withType(type); } // Is there an annotation

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> that specifies exact deserializer? JsonDeserializer<?> deser = findDeserializerFromAnnotation(ctxt, param); // If yes, we are mostly done: type = modifyTypeByAnnotation(ctxt, param, type); // Type deserializer: either comes from property (and already resolved) TypeDeserializer typeDeser = (TypeDeserializer) type.getTypeHandler(); // or if not, based on type being referenced: if (typeDeser == null) { typeDeser = findTypeDeserializer(config, type); } // Note: contextualization of typeDeser _should_ occur in constructor of CreatorProperty // so it is not called directly here CreatorProperty prop = new CreatorProperty(name, type, property.getWrapperName(), typeDeser, beanDesc.getClassAnnotations(), param, index, injectableValueId, metadata); if (deser != null) { // As per [Issue#462] need to ensure we contextualize deserializer before passing it on deser = ctxt.handlePrimaryContextualization(deser, prop); prop = prop.withValueDeserializer(deser); } return prop; } protected PropertyName _findParamName(AnnotatedParameter param, AnnotationIntrospector intr) { if (param != null && intr != null) { PropertyName name = intr.findNameForDeserialization(param); if (name != null) { return name; } /* 14-Apr-2014, tatu: Need to also consider possible implicit name * (for JDK8, or via paranamer) */ String str = intr.findImplicitPropertyName(param); if (str != null && !str.isEmpty()) { return new PropertyName(str); } } return null; } /* /********************************************************** /* JsonDeserializerFactory impl: array deserializers /********************************************************** */ @Override public JsonDeserializer<?> createArrayDeserializer(DeserializationContext ctxt, ArrayType type, final BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); JavaType elemType = type.getContentType(); // Very first thing: is deserializer hard-coded for elements? JsonDeserializer<Object> contentDeser = elemType.getValueHandler(); // Then optional type

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> info (1.5): if type has been resolved, we may already know type deserializer: TypeDeserializer elemTypeDeser = elemType.getTypeHandler(); // but if not, may still be possible to find: if (elemTypeDeser == null) { elemTypeDeser = findTypeDeserializer(config, elemType); } // 23-Nov-2010, tatu: Custom array deserializer? JsonDeserializer<?> deser = _findCustomArrayDeserializer(type, config, beanDesc, elemTypeDeser, contentDeser); if (deser == null) { if (contentDeser == null) { Class<?> raw = elemType.getRawClass(); if (elemType.isPrimitive()) { return PrimitiveArrayDeserializers.forType(raw); } else if (raw == String.class) { return StringArrayDeserializer.instance; } } deser = new ObjectArrayDeserializer(type, contentDeser, elemTypeDeser); } // and then new with 2.2: ability to post-process it too (Issue#120) if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyArrayDeserializer(config, type, beanDesc, deser); } } return deser; } protected JsonDeserializer<?> _findCustomArrayDeserializer(ArrayType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { for (Deserializers d : _factoryConfig.deserializers()) { JsonDeserializer<?> deser = d.findArrayDeserializer(type, config, beanDesc, elementTypeDeserializer, elementDeserializer); if (deser != null) { return deser; } } return null; } /* /********************************************************** /* JsonDeserializerFactory impl: Collection(-like) deserializers /********************************************************** */ @Override public JsonDeserializer<?> createCollectionDeserializer(DeserializationContext ctxt, CollectionType type, BeanDescription beanDesc) throws JsonMappingException { JavaType contentType = type.getContentType(); // Very first thing: is deserializer hard-coded for elements? JsonDeserializer<Object> contentDeser = contentType

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>#161]: No default constructor for ArrayBlockingQueue... if (type.getRawClass() == ArrayBlockingQueue.class) { return new ArrayBlockingQueueDeserializer(type, contentDeser, contentTypeDeser, inst, null); } } // 13-Dec-2010, tatu: Can use more optimal deserializer if content type is String, so: if (contentType.getRawClass() == String.class) { // no value type deserializer because Strings are one of natural/native types: deser = new StringCollectionDeserializer(type, contentDeser, inst); } else { deser = new CollectionDeserializer(type, contentDeser, contentTypeDeser, inst); } } } // and then new with 2.2: ability to post-process it too (Issue#120) if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyCollectionDeserializer(config, type, beanDesc, deser); } } return deser; } protected CollectionType _mapAbstractCollectionType(JavaType type, DeserializationConfig config) { Class<?> collectionClass = type.getRawClass(); collectionClass = _collectionFallbacks.get(collectionClass.getName()); if (collectionClass == null) { return null; } return (CollectionType) config.constructSpecializedType(type, collectionClass); } protected JsonDeserializer<?> _findCustomCollectionDeserializer(CollectionType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { for (Deserializers d : _factoryConfig.deserializers()) { JsonDeserializer<?> deser = d.findCollectionDeserializer(type, config, beanDesc, elementTypeDeserializer, elementDeserializer); if (deser != null) { return deser; } } return null; } // Copied almost verbatim from "createCollectionDeserializer" -- should try to share more code @Override public JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationContext ctxt, CollectionLikeType type, final BeanDescription beanDesc) throws JsonMappingException { JavaType contentType = type.getContentType(); // Very first thing: is deserializer

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> hard-coded for elements? JsonDeserializer<Object> contentDeser = contentType.getValueHandler(); final DeserializationConfig config = ctxt.getConfig(); // Then optional type info (1.5): if type has been resolved, we may already know type deserializer: TypeDeserializer contentTypeDeser = contentType.getTypeHandler(); // but if not, may still be possible to find: if (contentTypeDeser == null) { contentTypeDeser = findTypeDeserializer(config, contentType); } JsonDeserializer<?> deser = _findCustomCollectionLikeDeserializer(type, config, beanDesc, contentTypeDeser, contentDeser); if (deser != null) { // and then new with 2.2: ability to post-process it too (Issue#120) if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyCollectionLikeDeserializer(config, type, beanDesc, deser); } } } return deser; } protected JsonDeserializer<?> _findCustomCollectionLikeDeserializer(CollectionLikeType type, DeserializationConfig config, BeanDescription beanDesc, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { for (Deserializers d : _factoryConfig.deserializers()) { JsonDeserializer<?> deser = d.findCollectionLikeDeserializer(type, config, beanDesc, elementTypeDeserializer, elementDeserializer); if (deser != null) { return deser; } } return null; } /* /********************************************************** /* JsonDeserializerFactory impl: Map(-like) deserializers /********************************************************** */ @Override public JsonDeserializer<?> createMapDeserializer(DeserializationContext ctxt, MapType type, BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); JavaType keyType = type.getKeyType(); JavaType contentType = type.getContentType(); // First: is there annotation-specified deserializer for values? @SuppressWarnings("unchecked") JsonDeserializer<Object> contentDeser = (JsonDeserializer<Object>) contentType.getValueHandler(); // Ok: need a key deserializer (null indicates 'default' here) KeyDeserializer keyDes = (KeyDeserializer) keyType.getValueHandler();

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>concrete Map type "+type); } deser = AbstractDeserializer.constructForNonPOJO(beanDesc); } } if (deser == null) { ValueInstantiator inst = findValueInstantiator(ctxt, beanDesc); MapDeserializer md = new MapDeserializer(type, inst, keyDes, contentDeser, contentTypeDeser); md.setIgnorableProperties(config.getAnnotationIntrospector().findPropertiesToIgnore(beanDesc.getClassInfo())); deser = md; } } } // and then new with 2.2: ability to post-process it too (Issue#120) if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyMapDeserializer(config, type, beanDesc, deser); } } return deser; } // Copied almost verbatim from "createMapDeserializer" -- should try to share more code @Override public JsonDeserializer<?> createMapLikeDeserializer(DeserializationContext ctxt, MapLikeType type, final BeanDescription beanDesc) throws JsonMappingException { JavaType keyType = type.getKeyType(); JavaType contentType = type.getContentType(); final DeserializationConfig config = ctxt.getConfig(); // First: is there annotation-specified deserializer for values? @SuppressWarnings("unchecked") JsonDeserializer<Object> contentDeser = (JsonDeserializer<Object>) contentType.getValueHandler(); // Ok: need a key deserializer (null indicates 'default' here) KeyDeserializer keyDes = (KeyDeserializer) keyType.getValueHandler(); /* !!! 24-Jan-2012, tatu: NOTE: impls MUST use resolve() to find key deserializer! if (keyDes == null) { keyDes = p.findKeyDeserializer(config, keyType, property); } */ // Then optional type info (1.5); either attached to type, or resolve separately: TypeDeserializer contentTypeDeser = contentType.getTypeHandler(); // but if not, may still be possible to find: if (contentTypeDeser == null) { contentTypeDeser = findTypeDeserializer(config, contentType); } JsonDeserializer<?> deser = _findCustomMapLikeDeserializer(type, config, beanDesc, key

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Des, contentTypeDeser, contentDeser); if (deser != null) { // and then new with 2.2: ability to post-process it too (Issue#120) if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyMapLikeDeserializer(config, type, beanDesc, deser); } } } return deser; } protected JsonDeserializer<?> _findCustomMapDeserializer(MapType type, DeserializationConfig config, BeanDescription beanDesc, KeyDeserializer keyDeserializer, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { for (Deserializers d : _factoryConfig.deserializers()) { JsonDeserializer<?> deser = d.findMapDeserializer(type, config, beanDesc, keyDeserializer, elementTypeDeserializer, elementDeserializer); if (deser != null) { return deser; } } return null; } protected JsonDeserializer<?> _findCustomMapLikeDeserializer(MapLikeType type, DeserializationConfig config, BeanDescription beanDesc, KeyDeserializer keyDeserializer, TypeDeserializer elementTypeDeserializer, JsonDeserializer<?> elementDeserializer) throws JsonMappingException { for (Deserializers d : _factoryConfig.deserializers()) { JsonDeserializer<?> deser = d.findMapLikeDeserializer(type, config, beanDesc, keyDeserializer, elementTypeDeserializer, elementDeserializer); if (deser != null) { return deser; } } return null; } /* /********************************************************** /* JsonDeserializerFactory impl: Enum deserializers /********************************************************** */ /** * Factory method for constructing serializers of {@link Enum} types. */ @Override public JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); final Class<?> enumClass = type.getRawClass(); // 23-Nov-2010, tatu: Custom deserializer? JsonDeserializer<?> deser = _findCustomEnumDeserializer(enumClass, config, beanDesc); if (deser == null) { // [JACKSON-193] May have @JsonCreator

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> for static factory method: for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) { if (ctxt.getAnnotationIntrospector().hasCreatorAnnotation(factory)) { int argCount = factory.getParameterCount(); if (argCount == 1) { Class<?> returnType = factory.getRawReturnType(); // usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?) if (returnType.isAssignableFrom(enumClass)) { deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory); break; } } throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type " +enumClass.getName()+")"); } } // [JACKSON-749] Also, need to consider @JsonValue, if one found if (deser == null) { deser = new EnumDeserializer(constructEnumResolver(enumClass, config, beanDesc.findJsonValueMethod())); } } // and then new with 2.2: ability to post-process it too (Issue#120) if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyEnumDeserializer(config, type, beanDesc, deser); } } return deser; } protected JsonDeserializer<?> _findCustomEnumDeserializer(Class<?> type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { for (Deserializers d : _factoryConfig.deserializers()) { JsonDeserializer<?> deser = d.findEnumDeserializer(type, config, beanDesc); if (deser != null) { return deser; } } return null; } /* /********************************************************** /* JsonDeserializerFactory impl: Tree deserializers /********************************************************** */ @Override public JsonDeserializer<?> createTreeDeserializer(DeserializationConfig config, JavaType nodeType, BeanDescription beanDesc) throws JsonMappingException { @SuppressWarnings("unchecked") Class<? extends JsonNode> nodeClass = (Class<? extends JsonNode>) nodeType.getRawClass(); // 23-Nov-2010, tatu: Custom deserializer? JsonDeserializer<?> custom = _findCustomTreeNodeDeserializer(nodeClass,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> config, beanDesc); if (custom != null) { return custom; } return JsonNodeDeserializer.getDeserializer(nodeClass); } protected JsonDeserializer<?> _findCustomTreeNodeDeserializer(Class<? extends JsonNode> type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { for (Deserializers d : _factoryConfig.deserializers()) { JsonDeserializer<?> deser = d.findTreeNodeDeserializer(type, config, beanDesc); if (deser != null) { return deser; } } return null; } /* /********************************************************** /* JsonDeserializerFactory impl (partial): type deserializers /********************************************************** */ @Override public TypeDeserializer findTypeDeserializer(DeserializationConfig config, JavaType baseType) throws JsonMappingException { BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass()); AnnotatedClass ac = bean.getClassInfo(); AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType); /* Ok: if there is no explicit type info handler, we may want to * use a default. If so, config object knows what to use. */ Collection<NamedType> subtypes = null; if (b == null) { b = config.getDefaultTyper(baseType); if (b == null) { return null; } } else { subtypes = config.getSubtypeResolver().collectAndResolveSubtypes(ac, config, ai); } // [JACKSON-505]: May need to figure out default implementation, if none found yet // (note: check for abstract type is not 100% mandatory, more of an optimization) if ((b.getDefaultImpl() == null) && baseType.isAbstract()) { JavaType defaultType = mapAbstractType(config, baseType); if (defaultType != null && defaultType.getRawClass() != baseType.getRawClass()) { b = b.defaultImpl(defaultType.getRawClass()); } } return b.buildTypeDeserializer(config, baseType, subtypes); } /* /********************************************************** /* JsonDeserializerFactory impl (partial): key deserializers /********************************************************

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>** */ @Override public KeyDeserializer createKeyDeserializer(DeserializationContext ctxt, JavaType type) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); KeyDeserializer deser = null; if (_factoryConfig.hasKeyDeserializers()) { BeanDescription beanDesc = config.introspectClassAnnotations(type.getRawClass()); for (KeyDeserializers d : _factoryConfig.keyDeserializers()) { deser = d.findKeyDeserializer(type, config, beanDesc); if (deser != null) { break; } } } // the only non-standard thing is this: if (deser == null) { if (type.isEnumType()) { return _createEnumKeyDeserializer(ctxt, type); } deser = StdKeyDeserializers.findStringBasedKeyDeserializer(config, type); } // and then new with 2.2: ability to post-process it too (Issue#120) if (deser != null) { if (_factoryConfig.hasDeserializerModifiers()) { for (BeanDeserializerModifier mod : _factoryConfig.deserializerModifiers()) { deser = mod.modifyKeyDeserializer(config, type, deser); } } } return deser; } private KeyDeserializer _createEnumKeyDeserializer(DeserializationContext ctxt, JavaType type) throws JsonMappingException { final DeserializationConfig config = ctxt.getConfig(); BeanDescription beanDesc = config.introspect(type); JsonDeserializer<?> des = findDeserializerFromAnnotation(ctxt, beanDesc.getClassInfo()); if (des != null) { return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, des); } Class<?> enumClass = type.getRawClass(); // 23-Nov-2010, tatu: Custom deserializer? JsonDeserializer<?> custom = _findCustomEnumDeserializer(enumClass, config, beanDesc); if (custom != null) { return StdKeyDeserializers.constructDelegatingKeyDeserializer(config, type, custom); } EnumResolver<?> enumRes = constructEnumResolver(enumClass, config, beanDesc.findJsonValueMethod()); // [JACKSON-193] May have @JsonCreator for static factory method: for (AnnotatedMethod factory

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> : beanDesc.getFactoryMethods()) { if (config.getAnnotationIntrospector().hasCreatorAnnotation(factory)) { int argCount = factory.getParameterCount(); if (argCount == 1) { Class<?> returnType = factory.getRawReturnType(); // usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?) if (returnType.isAssignableFrom(enumClass)) { // note: mostly copied from 'EnumDeserializer.deserializerForCreator(...)' if (factory.getGenericParameterType(0) != String.class) { throw new IllegalArgumentException("Parameter #0 type for factory method ("+factory+") not suitable, must be java.lang.String"); } if (config.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(factory.getMember()); } return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes, factory); } } throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type " +enumClass.getName()+")"); } } // [JACKSON-749] Also, need to consider @JsonValue, if one found return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes); } /* /********************************************************** /* Extended API /********************************************************** */ /** * Method called to create a type information deserializer for values of * given non-container property, if one is needed. * If not needed (no polymorphic handling configured for property), should return null. *<p> * Note that this method is only called for non-container bean properties, * and not for values in container types or root values (or container properties) * * @param baseType Declared base type of the value to deserializer (actual * deserializer type will be this type or its subtype) * * @return Type deserializer to use for given base type, if one is needed; null if not. */ public TypeDeserializer findPropertyTypeDeserializer(DeserializationConfig config, JavaType baseType, AnnotatedMember annotated) throws JsonMappingException { AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findPropertyTypeResolver(config, annotated, baseType); // Defaulting: if no annotations

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> on member, check value class if (b == null) { return findTypeDeserializer(config, baseType); } // but if annotations found, may need to resolve subtypes: Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypes( annotated, config, ai, baseType); return b.buildTypeDeserializer(config, baseType, subtypes); } /** * Method called to find and create a type information deserializer for values of * given container (list, array, map) property, if one is needed. * If not needed (no polymorphic handling configured for property), should return null. *<p> * Note that this method is only called for container bean properties, * and not for values in container types or root values (or non-container properties) * * @param containerType Type of property; must be a container type * @param propertyEntity Field or method that contains container property */ public TypeDeserializer findPropertyContentTypeDeserializer(DeserializationConfig config, JavaType containerType, AnnotatedMember propertyEntity) throws JsonMappingException { AnnotationIntrospector ai = config.getAnnotationIntrospector(); TypeResolverBuilder<?> b = ai.findPropertyContentTypeResolver(config, propertyEntity, containerType); JavaType contentType = containerType.getContentType(); // Defaulting: if no annotations on member, check class if (b == null) { return findTypeDeserializer(config, contentType); } // but if annotations found, may need to resolve subtypes: Collection<NamedType> subtypes = config.getSubtypeResolver().collectAndResolveSubtypes( propertyEntity, config, ai, contentType); return b.buildTypeDeserializer(config, contentType, subtypes); } /** * Helper method called to find one of default serializers for "well-known" * platform types: JDK-provided types, and small number of public Jackson * API types. * * @since 2.2 */ public JsonDeserializer<?> findDefaultDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException { Class<?> rawType = type.getRawClass(); // Object ("untyped"), String equivalents: if (rawType == CLASS_OBJECT) { return new Untyped

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>ObjectDeserializer(); } if (rawType == CLASS_STRING || rawType == CLASS_CHAR_BUFFER) { return StringDeserializer.instance; } if (rawType == CLASS_ITERABLE) { // [Issue#199]: Can and should 'upgrade' to a Collection type: TypeFactory tf = ctxt.getTypeFactory(); JavaType elemType = (type.containedTypeCount() > 0) ? type.containedType(0) : TypeFactory.unknownType(); CollectionType ct = tf.constructCollectionType(Collection.class, elemType); // Should we re-introspect beanDesc? For now let's not... return createCollectionDeserializer(ctxt, ct, beanDesc); } String clsName = rawType.getName(); if (rawType.isPrimitive() || clsName.startsWith("java.")) { // Primitives/wrappers, other Numbers: JsonDeserializer<?> deser = NumberDeserializers.find(rawType, clsName); if (deser == null) { deser = DateDeserializers.find(rawType, clsName); } if (deser != null) { return deser; } } // and a few Jackson types as well: if (rawType == TokenBuffer.class) { return new TokenBufferDeserializer(); } return JdkDeserializers.find(rawType, clsName); } /* /********************************************************** /* Helper methods, value/content/key type introspection /********************************************************** */ /** * Helper method called to check if a class or method * has annotation that tells which class to use for deserialization. * Returns null if no such annotation found. */ protected JsonDeserializer<Object> findDeserializerFromAnnotation(DeserializationContext ctxt, Annotated ann) throws JsonMappingException { Object deserDef = ctxt.getAnnotationIntrospector().findDeserializer(ann); if (deserDef == null) { return null; } return ctxt.deserializerInstance(ann, deserDef); } /** * Method called to see if given method has annotations that indicate * a more specific type than what the argument specifies. * If annotations are present, they must specify compatible Class; * instance of which can be assigned using the method. This means * that the Class has to be

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> raw class of type, or its sub-class * (or, implementing class if original Class instance is an interface). * * @param a Method or field that the type is associated with * @param type Type of field, or the setter argument * * @return Original type if no annotations are present; or a more * specific type derived from it if type annotation(s) was found * * @throws JsonMappingException if invalid annotation is found */ @SuppressWarnings({ "unchecked" }) protected <T extends JavaType> T modifyTypeByAnnotation(DeserializationContext ctxt, Annotated a, T type) throws JsonMappingException { // first: let's check class for the instance itself: AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); Class<?> subclass = intr.findDeserializationType(a, type); if (subclass != null) { try { type = (T) type.narrowBy(subclass); } catch (IllegalArgumentException iae) { throw new JsonMappingException("Failed to narrow type "+type+" with concrete-type annotation (value "+subclass.getName()+"), method '"+a.getName()+"': "+iae.getMessage(), null, iae); } } // then key class if (type.isContainerType()) { Class<?> keyClass = intr.findDeserializationKeyType(a, type.getKeyType()); if (keyClass != null) { // illegal to use on non-Maps if (!(type instanceof MapLikeType)) { throw new JsonMappingException("Illegal key-type annotation: type "+type+" is not a Map(-like) type"); } try { type = (T) ((MapLikeType) type).narrowKey(keyClass); } catch (IllegalArgumentException iae) { throw new JsonMappingException("Failed to narrow key type "+type+" with key-type annotation ("+keyClass.getName()+"): "+iae.getMessage(), null, iae); } } JavaType keyType = type.getKeyType(); /* 21-Mar-2011, tatu: ... and associated deserializer too (unless already assigned) * (not 100% why or how, but this does seem to get called more than once, which * is not good: for now, let's

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> just avoid errors) */ if (keyType != null && keyType.getValueHandler() == null) { Object kdDef = intr.findKeyDeserializer(a); KeyDeserializer kd = ctxt.keyDeserializerInstance(a, kdDef); if (kd != null) { type = (T) ((MapLikeType) type).withKeyValueHandler(kd); keyType = type.getKeyType(); // just in case it's used below } } // and finally content class; only applicable to structured types Class<?> cc = intr.findDeserializationContentType(a, type.getContentType()); if (cc != null) { try { type = (T) type.narrowContentsBy(cc); } catch (IllegalArgumentException iae) { throw new JsonMappingException("Failed to narrow content type "+type+" with content-type annotation ("+cc.getName()+"): "+iae.getMessage(), null, iae); } } // ... as well as deserializer for contents: JavaType contentType = type.getContentType(); if (contentType.getValueHandler() == null) { // as with above, avoid resetting (which would trigger exception) Object cdDef = intr.findContentDeserializer(a); JsonDeserializer<?> cd = ctxt.deserializerInstance(a, cdDef); if (cd != null) { type = (T) type.withContentValueHandler(cd); } } } return type; } /** * Helper method used to resolve method return types and field * types. The main trick here is that the containing bean may * have type variable binding information (when deserializing * using generic type passed as type reference), which is * needed in some cases. */ protected JavaType resolveType(DeserializationContext ctxt, BeanDescription beanDesc, JavaType type, AnnotatedMember member) throws JsonMappingException { // [JACKSON-154]: Also need to handle keyUsing, contentUsing if (type.isContainerType()) { AnnotationIntrospector intr = ctxt.getAnnotationIntrospector(); JavaType keyType = type.getKeyType(); if (keyType != null) { Object kdDef = intr.findKeyDeserializer(member); KeyDeserializer kd = ctxt.keyDeserializerInstance(member, k

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> /** * Convenience method for creating a new factory instance with additional deserializer * provider. */ public abstract DeserializerFactory withAdditionalDeserializers(Deserializers additional); /** * Convenience method for creating a new factory instance with additional * {@link KeyDeserializers}. */ public abstract DeserializerFactory withAdditionalKeyDeserializers(KeyDeserializers additional); /** * Convenience method for creating a new factory instance with additional * {@link BeanDeserializerModifier}. */ public abstract DeserializerFactory withDeserializerModifier(BeanDeserializerModifier modifier); /** * Convenience method for creating a new factory instance with additional * {@link AbstractTypeResolver}. */ public abstract DeserializerFactory withAbstractTypeResolver(AbstractTypeResolver resolver); /** * Convenience method for creating a new factory instance with additional * {@link ValueInstantiators}. */ public abstract DeserializerFactory withValueInstantiators(ValueInstantiators instantiators); /* /********************************************************** /* Basic DeserializerFactory API: /********************************************************** */ /** * Method that can be called to try to resolve an abstract type * (interface, abstract class) into a concrete type, or at least * something "more concrete" (abstract class instead of interface). * Will either return passed type, or a more specific type. */ public abstract JavaType mapAbstractType(DeserializationConfig config, JavaType type) throws JsonMappingException; /** * Method that is to find all creators (constructors, factory methods) * for the bean type to deserialize. */ public abstract ValueInstantiator findValueInstantiator(DeserializationContext ctxt, BeanDescription beanDesc) throws JsonMappingException; /** * Method called to create (or, for completely immutable deserializers, * reuse) a deserializer that can convert JSON content into values of * specified Java "bean" (POJO) type. * At this point it is known that the type is not otherwise recognized * as one of structured types (array, Collection, Map) or a well-known * JDK type (enum, primitives/wrappers, String); this method only * gets called if other options are exhausted. This also means that * this method can be overridden to add support for custom types. * * @param type Type to be deserialized */ public abstract JsonDeserializer<Object> createBeanDeserializer(Deserialization

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Context ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException; /** * Method called to create a deserializer that will use specified Builder * class for building value instances. * * @since 2.0 */ public abstract JsonDeserializer<Object> createBuilderBasedDeserializer( DeserializationContext ctxt, JavaType type, BeanDescription beanDesc, Class<?> builderClass) throws JsonMappingException; /** * Method called to create (or, for completely immutable deserializers, * reuse) a deserializer that can convert JSON content into values of * specified Java type. * * @param type Type to be deserialized */ public abstract JsonDeserializer<?> createArrayDeserializer(DeserializationContext ctxt, ArrayType type, BeanDescription beanDesc) throws JsonMappingException; public abstract JsonDeserializer<?> createCollectionDeserializer(DeserializationContext ctxt, CollectionType type, BeanDescription beanDesc) throws JsonMappingException; public abstract JsonDeserializer<?> createCollectionLikeDeserializer(DeserializationContext ctxt, CollectionLikeType type, BeanDescription beanDesc) throws JsonMappingException; public abstract JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt, JavaType type, BeanDescription beanDesc) throws JsonMappingException; public abstract JsonDeserializer<?> createMapDeserializer(DeserializationContext ctxt, MapType type, BeanDescription beanDesc) throws JsonMappingException; public abstract JsonDeserializer<?> createMapLikeDeserializer(DeserializationContext ctxt, MapLikeType type, BeanDescription beanDesc) throws JsonMappingException; /** * Method called to create and return a deserializer that can construct * JsonNode(s) from JSON content. */ public abstract JsonDeserializer<?> createTreeDeserializer(DeserializationConfig config, JavaType type, BeanDescription beanDesc) throws JsonMappingException; /** * Method called to find if factory knows how to create a key deserializer * for specified type; currently this means checking if a module has registered * possible deserializers. * * @return Key deserializer to use for specified type, if one found; null if not * (and default key deserializer should be used) */ public abstract KeyDeserializer createKeyDeserializer(DeserializationContext ctxt, JavaType type) throws JsonMappingException; /** * Method called to find and create a type information deserializer for given base type,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> * if one is needed. If not needed (no polymorphic handling configured for type), * should return null. *<p> * Note that this method is usually only directly called for values of container (Collection, * array, Map) types and root values, but not for bean property values. * * @param baseType Declared base type of the value to deserializer (actual * deserializer type will be this type or its subtype) * * @return Type deserializer to use for given base type, if one is needed; null if not. */ public abstract TypeDeserializer findTypeDeserializer(DeserializationConfig config, JavaType baseType) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.ser.std; import java.io.IOException; import java.lang.reflect.Type; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper; /** * This is the special serializer for regular {@link java.lang.String}s. *<p> * Since this is one of "native" types, no type information is ever * included on serialization (unlike for most scalar types as of 1.5) */ @JacksonStdImpl public final class StringSerializer extends NonTypedScalarSerializerBase<String> { public StringSerializer() { super(String.class); } /** * For Strings, both null and Empty String qualify for emptiness. */ @Override public boolean isEmpty(String value) { return (value == null) || (value.length() == 0); } @Override public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException { jgen.writeString(value); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { return createSchemaNode("string", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { if (visitor != null) visitor.expectStringFormat(typeHint); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> _elementTypeDeserializer)) { return this; } return new ObjectArrayDeserializer(_arrayType, (JsonDeserializer<Object>) elemDeser, elemTypeDeser); } @Override public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { JsonDeserializer<?> deser = _elementDeserializer; // #125: May have a content converter deser = findConvertingContentDeserializer(ctxt, property, deser); if (deser == null) { deser = ctxt.findContextualValueDeserializer(_arrayType.getContentType(), property); } else { // if directly assigned, probably not yet contextual, so: deser = ctxt.handleSecondaryContextualization(deser, property); } TypeDeserializer elemTypeDeser = _elementTypeDeserializer; if (elemTypeDeser != null) { elemTypeDeser = elemTypeDeser.forProperty(property); } return withDeserializer(elemTypeDeser, deser); } /* /********************************************************** /* ContainerDeserializerBase API /********************************************************** */ @Override public JavaType getContentType() { return _arrayType.getContentType(); } @Override public JsonDeserializer<Object> getContentDeserializer() { return _elementDeserializer; } /* /********************************************************** /* JsonDeserializer API /********************************************************** */ @Override public Object[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; final TypeDeserializer typeDeser = _elementTypeDeserializer; try { while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Note: must handle null explicitly here; value deserializers won't Object value; if (t == JsonToken.VALUE_NULL) { value = _elementDeserializer.getNullValue(); } else if (typeDeser == null) { value = _elementDeserializer.deserialize(jp, ctxt); } else { value = _element

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Deserializer.deserializeWithType(jp, ctxt, typeDeser); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } } catch (Exception e) { // note: pass Object.class, not Object[].class, as we need element type for error info throw JsonMappingException.wrapWithPath(e, Object.class, ix); } Object[] result; if (_untyped) { result = buffer.completeAndClearBuffer(chunk, ix); } else { result = buffer.completeAndClearBuffer(chunk, ix, _elementClass); } ctxt.returnObjectBuffer(buffer); return result; } @Override public Object[] deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException, JsonProcessingException { /* Should there be separate handling for base64 stuff? * for now this should be enough: */ return (Object[]) typeDeserializer.deserializeTypedFromArray(jp, ctxt); } /* /********************************************************** /* Internal methods /********************************************************** */ protected Byte[] deserializeFromBase64(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // First same as what PrimitiveArrayDeserializers.ByteDeser does: byte[] b = jp.getBinaryValue(ctxt.getBase64Variant()); // But then need to convert to wrappers Byte[] result = new Byte[b.length]; for (int i = 0, len = b.length; i < len; ++i) { result[i] = Byte.valueOf(b[i]); } return result; } private final Object[] handleNonArray(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { // [JACKSON-620] Empty String can become null... if ((jp.getCurrentToken() == JsonToken.VALUE_STRING) && ctxt.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) { String str = jp.getText(); if (str.length() == 0) { return null; } } // Can we do implicit coercion

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> } it.next(); return !it.hasNext(); } /* /********************************************************** /* Actual serialization /********************************************************** */ @Override public void serializeContents(Collection<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException { if (_elementSerializer != null) { serializeContentsUsing(value, jgen, provider, _elementSerializer); return; } Iterator<?> it = value.iterator(); if (!it.hasNext()) { return; } PropertySerializerMap serializers = _dynamicSerializers; final TypeSerializer typeSer = _valueTypeSerializer; int i = 0; try { do { Object elem = it.next(); if (elem == null) { provider.defaultSerializeNull(jgen); } else { Class<?> cc = elem.getClass(); JsonSerializer<Object> serializer = serializers.serializerFor(cc); if (serializer == null) { // To fix [JACKSON-508] if (_elementType.hasGenericTypes()) { serializer = _findAndAddDynamic(serializers, provider.constructSpecializedType(_elementType, cc), provider); } else { serializer = _findAndAddDynamic(serializers, cc, provider); } serializers = _dynamicSerializers; } if (typeSer == null) { serializer.serialize(elem, jgen, provider); } else { serializer.serializeWithType(elem, jgen, provider, typeSer); } } ++i; } while (it.hasNext()); } catch (Exception e) { // [JACKSON-55] Need to add reference information wrapAndThrow(provider, e, value, i); } } public void serializeContentsUsing(Collection<?> value, JsonGenerator jgen, SerializerProvider provider, JsonSerializer<Object> ser) throws IOException, JsonGenerationException { Iterator<?> it = value.iterator(); if (it.hasNext()) { TypeSerializer typeSer = _valueTypeSerializer; int i = 0; do { Object elem = it.next(); try { if (elem == null) { provider.defaultSerializeNull(jgen); } else { if (typeSer == null) { ser.serialize(elem,

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> jgen, provider); } else { ser.serializeWithType(elem, jgen, provider, typeSer); } } ++i; } catch (Exception e) { // [JACKSON-55] Need to add reference information wrapAndThrow(provider, e, value, i); } } while (it.hasNext()); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser; import com.fasterxml.jackson.databind.*; /** * Add-on interface that {@link JsonDeserializer}s can implement to get a callback * that can be used to create contextual (context-dependent) instances of * deserializer to use for handling properties of supported type. * This can be useful * for deserializers that can be configured by annotations, or should otherwise * have differing behavior depending on what kind of property is being deserialized. *<p> * Note that in cases where deserializer needs both contextualization and * resolution -- that is, implements both this interface and {@link ResolvableDeserializer} * -- resolution via {@link ResolvableDeserializer} occurs first, and contextual * resolution (via this interface) later on. */ public interface ContextualDeserializer { /** * Method called to see if a different (or differently configured) deserializer * is needed to deserialize values of specified property. * Note that instance that this method is called on is typically shared one and * as a result method should <b>NOT</b> modify this instance but rather construct * and return a new instance. This instance should only be returned as-is, in case * it is already suitable for use. * * @param ctxt Deserialization context to access configuration, additional * deserializers that may be needed by this deserializer * @param property Method, field or constructor parameter that represents the property * (and is used to assign deserialized value). * Should be available; but there may be cases where caller can not provide it and * null is passed instead (in which case impls usually pass 'this' deserializer as is) * * @return Deserializer to use for deserializing values of specified property; * may be this instance or a new instance. * * @throws JsonMappingException */ public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser.impl; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; /** * Special bogus "serializer" that will throw * {@link JsonMappingException} if an attempt is made to deserialize * a value. This is used as placeholder to avoid NPEs for uninitialized * structured serializers or handlers. */ public class FailingDeserializer extends StdDeserializer<Object> { private static final long serialVersionUID = 1L; protected final String _message; public FailingDeserializer(String m) { super(Object.class); _message = m; } @Override public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws JsonMappingException{ throw ctxt.mappingException(_message); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } handleUnknownVanilla(jp, ctxt, bean, propName); } return bean; } /* /********************************************************** /* Concrete deserialization methods /********************************************************** */ /** * Streamlined version that is only used when no "special" * features are enabled. */ private final Object vanillaDeserialize(JsonParser jp, DeserializationContext ctxt, JsonToken t) throws IOException, JsonProcessingException { final Object bean = _valueInstantiator.createUsingDefault(ctxt); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); // Skip field name: jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { // normal case try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } } else { handleUnknownVanilla(jp, ctxt, bean, propName); } } return bean; } /** * General version used when handling needs more advanced * features. */ @Override public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (_nonStandardCreation) { if (_unwrappedPropertyHandler != null) { return deserializeWithUnwrapped(jp, ctxt); } if (_externalTypeIdHandler != null) { return deserializeWithExternalTypeId(jp, ctxt); } Object bean = deserializeFromObjectUsingNonDefault(jp, ctxt); if (_injectables != null) { injectValues(ctxt, bean); } /* 27-May-2014, tatu: I don't think view processing would work * at this point, so commenting it out; but leaving in place * just in case I forgot something fundamental... */ /* if (_needViewProcesing) { Class<?> view = ctxt.getActiveView(); if (view != null) { return deserializeWithView(jp, ctxt

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>, bean, view); } } */ return bean; } final Object bean = _valueInstantiator.createUsingDefault(ctxt); if (jp.canReadObjectId()) { Object id = jp.getObjectId(); if (id != null) { _handleTypedObjectId(jp, ctxt, bean, id); } } if (_injectables != null) { injectValues(ctxt, bean); } if (_needViewProcesing) { Class<?> view = ctxt.getActiveView(); if (view != null) { return deserializeWithView(jp, ctxt, bean, view); } } JsonToken t = jp.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); // Skip field name: jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { // normal case try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } handleUnknownVanilla(jp, ctxt, bean, propName); } return bean; } /** * Method called to deserialize bean using "property-based creator": * this means that a non-default constructor or factory method is * called, and then possibly other setters. The trick is that * values for creator method need to be buffered, first; and * due to non-guaranteed ordering possibly some other properties * as well. */ @Override @SuppressWarnings("resource") protected Object _deserializeUsingPropertyBased(final JsonParser jp, final DeserializationContext ctxt) throws IOException, JsonProcessingException { final PropertyBasedCreator creator = _propertyBasedCreator; PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader); // 04-Jan-2010, tatu: May need to collect unknown properties for polymorphic cases TokenBuffer unknown = null; JsonToken t = jp.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName();

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> jp.nextToken(); // to point to value // creator property? SettableBeanProperty creatorProp = creator.findCreatorProperty(propName); if (creatorProp != null) { // Last creator property to set? Object value = creatorProp.deserialize(jp, ctxt); if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) { jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt); bean = null; // never gets here } // polymorphic? if (bean.getClass() != _beanType.getRawClass()) { return handlePolymorphic(jp, ctxt, bean, unknown); } if (unknown != null) { // nope, just extra unknown stuff... bean = handleUnknownProperties(ctxt, bean, unknown); } // or just clean? return deserialize(jp, ctxt, bean); } continue; } // Object Id property? if (buffer.readIdProperty(propName)) { continue; } // regular property? needs buffering SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { buffer.bufferProperty(prop, prop.deserialize(jp, ctxt)); continue; } // As per [JACKSON-313], things marked as ignorable should not be // passed to any setter if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, handledType(), propName); continue; } // "any property"? if (_anySetter != null) { buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt)); continue; } // Ok then, let's collect the whole field; name and value if (unknown == null) { unknown = new TokenBuffer(jp); } unknown.writeFieldName(propName); unknown.copyCurrentStructure(jp); } // We hit END_OBJECT, so: Object bean; try { bean = creator.

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>build(ctxt, buffer); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); bean = null; // never gets here } if (unknown != null) { // polymorphic? if (bean.getClass() != _beanType.getRawClass()) { return handlePolymorphic(null, ctxt, bean, unknown); } // no, just some extra unknown properties return handleUnknownProperties(ctxt, bean, unknown); } return bean; } /* /********************************************************** /* Deserializing when we have to consider an active View /********************************************************** */ protected final Object deserializeWithView(JsonParser jp, DeserializationContext ctxt, Object bean, Class<?> activeView) throws IOException, JsonProcessingException { JsonToken t = jp.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); // Skip field name: jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { if (!prop.visibleInView(activeView)) { jp.skipChildren(); continue; } try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } handleUnknownVanilla(jp, ctxt, bean, propName); } return bean; } /* /********************************************************** /* Handling for cases where we have "unwrapped" values /********************************************************** */ /** * Method called when there are declared "unwrapped" properties * which need special handling */ @SuppressWarnings("resource") protected Object deserializeWithUnwrapped(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if (_delegateDeserializer != null) { return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); } if (_propertyBasedCreator != null) { return deserializeUsingPropertyBasedWithUnwrapped(jp, ctxt); } TokenBuffer tokens = new TokenBuffer(jp); tokens.writeStartObject(); final Object bean = _valueInstantiator.createUsingDefault(ctxt); if (_

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>injectables != null) { injectValues(ctxt, bean); } final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null; for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) { String propName = jp.getCurrentName(); jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { // normal case if (activeView != null && !prop.visibleInView(activeView)) { jp.skipChildren(); continue; } try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } // ignorable things should be ignored if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, bean, propName); continue; } // but... others should be passed to unwrapped property deserializers tokens.writeFieldName(propName); tokens.copyCurrentStructure(jp); // how about any setter? We'll get copies but... if (_anySetter != null) { try { _anySetter.deserializeAndSet(jp, ctxt, bean, propName); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } } tokens.writeEndObject(); _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens); return bean; } @SuppressWarnings("resource") protected Object deserializeWithUnwrapped(JsonParser jp, DeserializationContext ctxt, Object bean) throws IOException, JsonProcessingException { JsonToken t = jp.getCurrentToken(); if (t == JsonToken.START_OBJECT) { t = jp.nextToken(); } TokenBuffer tokens = new TokenBuffer(jp); tokens.writeStartObject(); final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null; for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); SettableBeanProperty prop = _beanProperties.find(prop

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Name); jp.nextToken(); if (prop != null) { // normal case if (activeView != null && !prop.visibleInView(activeView)) { jp.skipChildren(); continue; } try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, bean, propName); continue; } // but... others should be passed to unwrapped property deserializers tokens.writeFieldName(propName); tokens.copyCurrentStructure(jp); // how about any setter? We'll get copies but... if (_anySetter != null) { _anySetter.deserializeAndSet(jp, ctxt, bean, propName); } } tokens.writeEndObject(); _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens); return bean; } @SuppressWarnings("resource") protected Object deserializeUsingPropertyBasedWithUnwrapped(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { final PropertyBasedCreator creator = _propertyBasedCreator; PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader); TokenBuffer tokens = new TokenBuffer(jp); tokens.writeStartObject(); JsonToken t = jp.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); jp.nextToken(); // to point to value // creator property? SettableBeanProperty creatorProp = creator.findCreatorProperty(propName); if (creatorProp != null) { // Last creator property to set? Object value = creatorProp.deserialize(jp, ctxt); if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) { t = jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt); continue; //

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> never gets here } // if so, need to copy all remaining tokens into buffer while (t == JsonToken.FIELD_NAME) { jp.nextToken(); // to skip name tokens.copyCurrentStructure(jp); t = jp.nextToken(); } tokens.writeEndObject(); if (bean.getClass() != _beanType.getRawClass()) { // !!! 08-Jul-2011, tatu: Could probably support; but for now // it's too complicated, so bail out tokens.close(); throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values"); } return _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens); } continue; } // Object Id property? if (buffer.readIdProperty(propName)) { continue; } // regular property? needs buffering SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { buffer.bufferProperty(prop, prop.deserialize(jp, ctxt)); continue; } /* As per [JACKSON-313], things marked as ignorable should not be * passed to any setter */ if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, handledType(), propName); continue; } tokens.writeFieldName(propName); tokens.copyCurrentStructure(jp); // "any property"? if (_anySetter != null) { buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt)); } } // We hit END_OBJECT, so: Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); return null; // never gets here } return _unwrappedPropertyHandler.processUnwrapped(jp, ctxt, bean, tokens); } /* /********************************************************** /* Handling for cases where we have property/-ies with /* external type id /********************************************************** */ protected Object deserializeWithExternalTypeId(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { if

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> (_propertyBasedCreator != null) { return deserializeUsingPropertyBasedWithExternalTypeId(jp, ctxt); } return deserializeWithExternalTypeId(jp, ctxt, _valueInstantiator.createUsingDefault(ctxt)); } protected Object deserializeWithExternalTypeId(JsonParser jp, DeserializationContext ctxt, Object bean) throws IOException, JsonProcessingException { final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null; final ExternalTypeHandler ext = _externalTypeIdHandler.start(); JsonToken t = jp.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); jp.nextToken(); SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { // normal case // [JACKSON-831]: may have property AND be used as external type id: if (jp.getCurrentToken().isScalarValue()) { ext.handleTypePropertyValue(jp, ctxt, propName, bean); } if (activeView != null && !prop.visibleInView(activeView)) { jp.skipChildren(); continue; } try { prop.deserializeAndSet(jp, ctxt, bean); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } // ignorable things should be ignored if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, bean, propName); continue; } // but others are likely to be part of external type id thingy... if (ext.handlePropertyValue(jp, ctxt, propName, bean)) { continue; } // if not, the usual fallback handling: if (_anySetter != null) { try { _anySetter.deserializeAndSet(jp, ctxt, bean, propName); } catch (Exception e) { wrapAndThrow(e, bean, propName, ctxt); } continue; } // Unknown: let's call handler method handleUnknownProperty(jp, ctxt, bean, propName); } // and when we get this far, let's try finalizing the deal:

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> return ext.complete(jp, ctxt, bean); } @SuppressWarnings("resource") protected Object deserializeUsingPropertyBasedWithExternalTypeId(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { final ExternalTypeHandler ext = _externalTypeIdHandler.start(); final PropertyBasedCreator creator = _propertyBasedCreator; PropertyValueBuffer buffer = creator.startBuilding(jp, ctxt, _objectIdReader); TokenBuffer tokens = new TokenBuffer(jp); tokens.writeStartObject(); JsonToken t = jp.getCurrentToken(); for (; t == JsonToken.FIELD_NAME; t = jp.nextToken()) { String propName = jp.getCurrentName(); jp.nextToken(); // to point to value // creator property? SettableBeanProperty creatorProp = creator.findCreatorProperty(propName); if (creatorProp != null) { // first: let's check to see if this might be part of value with external type id: if (ext.handlePropertyValue(jp, ctxt, propName, buffer)) { ; } else { // Last creator property to set? Object value = creatorProp.deserialize(jp, ctxt); if (buffer.assignParameter(creatorProp.getCreatorIndex(), value)) { t = jp.nextToken(); // to move to following FIELD_NAME/END_OBJECT Object bean; try { bean = creator.build(ctxt, buffer); } catch (Exception e) { wrapAndThrow(e, _beanType.getRawClass(), propName, ctxt); continue; // never gets here } // if so, need to copy all remaining tokens into buffer while (t == JsonToken.FIELD_NAME) { jp.nextToken(); // to skip name tokens.copyCurrentStructure(jp); t = jp.nextToken(); } if (bean.getClass() != _beanType.getRawClass()) { // !!! 08-Jul-2011, tatu: Could probably support; but for now // it's too complicated, so bail out throw ctxt.mappingException("Can not create polymorphic instances with unwrapped values"); } return ext.complete(jp, ctxt, bean); } } continue; } // Object Id property? if (buffer.readIdProperty(

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>propName)) { continue; } // regular property? needs buffering SettableBeanProperty prop = _beanProperties.find(propName); if (prop != null) { buffer.bufferProperty(prop, prop.deserialize(jp, ctxt)); continue; } // external type id (or property that depends on it)? if (ext.handlePropertyValue(jp, ctxt, propName, null)) { continue; } /* As per [JACKSON-313], things marked as ignorable should not be * passed to any setter */ if (_ignorableProps != null && _ignorableProps.contains(propName)) { handleIgnoredProperty(jp, ctxt, handledType(), propName); continue; } // "any property"? if (_anySetter != null) { buffer.bufferAnyProperty(_anySetter, propName, _anySetter.deserialize(jp, ctxt)); } } // We hit END_OBJECT; resolve the pieces: try { return ext.complete(jp, ctxt, buffer, creator); } catch (Exception e) { wrapInstantiationProblem(e, ctxt); return null; // never gets here } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId; /** * Exception thrown during deserialization when there are object id that can't * be resolved. * * @author pgelinas */ public final class UnresolvedForwardReference extends JsonMappingException { private static final long serialVersionUID = 1L; private ReadableObjectId _roid; private List<UnresolvedId> _unresolvedIds; public UnresolvedForwardReference(String msg, JsonLocation loc, ReadableObjectId roid) { super(msg, loc); _roid = roid; } public UnresolvedForwardReference(String msg) { super(msg); _unresolvedIds = new ArrayList<UnresolvedId>(); } // ****************************** // ****** Accessor methods ****** // ****************************** public ReadableObjectId getRoid() { return _roid; } public Object getUnresolvedId() { return _roid.getKey().key; } public void addUnresolvedId(Object id, Class<?> type, JsonLocation where) { _unresolvedIds.add(new UnresolvedId(id, type, where)); } public List<UnresolvedId> getUnresolvedIds(){ return _unresolvedIds; } @Override public String getMessage() { String msg = super.getMessage(); if (_unresolvedIds == null) { return msg; } StringBuilder sb = new StringBuilder(msg); Iterator<UnresolvedId> iterator = _unresolvedIds.iterator(); while (iterator.hasNext()) { UnresolvedId unresolvedId = iterator.next(); sb.append(unresolvedId.toString()); if (iterator.hasNext()) { sb.append(", "); } } sb.append('.'); return sb.toString(); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.jsonschema; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.SerializerProvider; import java.lang.reflect.Type; /** * Marker interface for schema-aware serializers. */ public interface SchemaAware { /** * Get the representation of the schema to which this serializer will conform. * * @param provider The serializer provider. * @param typeHint A hint about the type. * @return <a href="http://json-schema.org/">Json-schema</a> for this serializer. */ public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException; /** * Get the representation of the schema to which this serializer will conform. * * @param provider The serializer provider. * @param isOptional Is the type optional * @param typeHint A hint about the type. * @return <a href="http://json-schema.org/">Json-schema</a> for this serializer. */ public JsonNode getSchema(SerializerProvider provider, Type typeHint, boolean isOptional) throws JsonMappingException; }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> serialize(value, jgen, provider); typeSer.writeTypeSuffixForScalar(value, jgen); } @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) { /* 01-Jan-2010, tatu: Not 100% sure what we should say here: * type is basically not known. This seems closest * approximation */ return createSchemaNode("any", true); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { /* 01-Jan-2010, tatu: Not 100% sure what we should say here: * type is basically not known. This seems closest * approximation */ visitor.expectAnyFormat(typeHint); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> int getParameterCount() { return _constructor.getParameterTypes().length; } @Override public Class<?> getRawParameterType(int index) { Class<?>[] types = _constructor.getParameterTypes(); return (index >= types.length) ? null : types[index]; } @Override public Type getGenericParameterType(int index) { Type[] types = _constructor.getGenericParameterTypes(); return (index >= types.length) ? null : types[index]; } @Override public final Object call() throws Exception { return _constructor.newInstance(); } @Override public final Object call(Object[] args) throws Exception { return _constructor.newInstance(args); } @Override public final Object call1(Object arg) throws Exception { return _constructor.newInstance(arg); } /* /********************************************************** /* AnnotatedMember impl /********************************************************** */ @Override public Class<?> getDeclaringClass() { return _constructor.getDeclaringClass(); } @Override public Member getMember() { return _constructor; } @Override public void setValue(Object pojo, Object value) throws UnsupportedOperationException { throw new UnsupportedOperationException("Cannot call setValue() on constructor of " +getDeclaringClass().getName()); } @Override public Object getValue(Object pojo) throws UnsupportedOperationException { throw new UnsupportedOperationException("Cannot call getValue() on constructor of " +getDeclaringClass().getName()); } /* /********************************************************** /* Extended API, specific annotations /********************************************************** */ @Override public String toString() { return "[constructor for "+getName()+", annotations: "+_annotations+"]"; } /* /********************************************************** /* JDK serialization handling /********************************************************** */ Object writeReplace() { return new AnnotatedConstructor(new Serialization(_constructor)); } Object readResolve() { Class<?> clazz = _serialization.clazz; try { Constructor<?> ctor = clazz.getDeclaredConstructor(_serialization.args); // 06-Oct-2012, tatu: Has "lost" its security override, must force back if (!ctor.isAccessible()) { ClassUtil.checkAndFixAccess(ctor); } return new AnnotatedConstructor(ctor, null, null); } catch (

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Exception e) { throw new IllegalArgumentException("Could not find constructor with " +_serialization.args.length+" args from Class '"+clazz.getName()); } } /** * Helper class that is used as the workaround to persist * Field references. It basically just stores declaring class * and field name. */ private final static class Serialization implements java.io.Serializable { private static final long serialVersionUID = 1L; protected Class<?> clazz; protected Class<?>[] args; public Serialization(Constructor<?> ctor) { clazz = ctor.getDeclaringClass(); args = ctor.getParameterTypes(); } } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> rest of ObjectCodec methods /********************************************************** */ @Override public <T> T treeToValue(TreeNode n, Class<T> valueType) throws JsonProcessingException { try { return readValue(treeAsTokens(n), valueType); } catch (JsonProcessingException e) { throw e; } catch (IOException e) { // should not occur, no real i/o... throw new IllegalArgumentException(e.getMessage(), e); } } @Override public void writeValue(JsonGenerator jgen, Object value) throws IOException, JsonProcessingException { throw new UnsupportedOperationException("Not implemented for ObjectReader"); } /* /********************************************************** /* Helper methods, data-binding /********************************************************** */ /** * Actual implementation of value reading+binding operation. */ protected Object _bind(JsonParser jp, Object valueToUpdate) throws IOException, JsonParseException, JsonMappingException { /* First: may need to read the next token, to initialize state (either * before first read from parser, or after previous token has been cleared) */ Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { if (valueToUpdate == null) { DeserializationContext ctxt = createDeserializationContext(jp, _config); result = _findRootDeserializer(ctxt, _valueType).getNullValue(); } else { result = valueToUpdate; } } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = valueToUpdate; } else { // pointing to event other than null DeserializationContext ctxt = createDeserializationContext(jp, _config); JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, _valueType); if (_unwrapRoot) { result = _unwrapAndDeserialize(jp, ctxt, _valueType, deser); } else { if (valueToUpdate == null) { result = deser.deserialize(jp, ctxt); } else { deser.deserialize(jp, ctxt, valueToUpdate); result = valueToUpdate; } } } // Need to consume the token too jp.clearCurrentToken(); return result; } protected Object _bindAndClose(JsonParser jp, Object valueToUpdate)

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> throws IOException, JsonParseException, JsonMappingException { if (_schema != null) { jp.setSchema(_schema); } try { Object result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL) { if (valueToUpdate == null) { DeserializationContext ctxt = createDeserializationContext(jp, _config); result = _findRootDeserializer(ctxt, _valueType).getNullValue(); } else { result = valueToUpdate; } } else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = valueToUpdate; } else { DeserializationContext ctxt = createDeserializationContext(jp, _config); JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, _valueType); if (_unwrapRoot) { result = _unwrapAndDeserialize(jp, ctxt, _valueType, deser); } else { if (valueToUpdate == null) { result = deser.deserialize(jp, ctxt); } else { deser.deserialize(jp, ctxt, valueToUpdate); result = valueToUpdate; } } } return result; } finally { try { jp.close(); } catch (IOException ioe) { } } } protected JsonNode _bindAsTree(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { JsonNode result; JsonToken t = _initForReading(jp); if (t == JsonToken.VALUE_NULL || t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) { result = NullNode.instance; } else { DeserializationContext ctxt = createDeserializationContext(jp, _config); JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, JSON_NODE_TYPE); if (_unwrapRoot) { result = (JsonNode) _unwrapAndDeserialize(jp, ctxt, JSON_NODE_TYPE, deser); } else { result = (JsonNode) deser.deserialize(jp, ctxt); } } // Need to consume the token too jp.clearCurrentToken(); return result; } protected JsonNode _bindAndCloseAsTree(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { if (_schema

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> != null) { jp.setSchema(_schema); } try { return _bindAsTree(jp); } finally { try { jp.close(); } catch (IOException ioe) { } } } /** * @since 2.1 */ protected <T> MappingIterator<T> _bindAndReadValues(JsonParser p, Object valueToUpdate) throws IOException, JsonProcessingException { if (_schema != null) { p.setSchema(_schema); } p.nextToken(); DeserializationContext ctxt = createDeserializationContext(p, _config); return new MappingIterator<T>(_valueType, p, ctxt, _findRootDeserializer(ctxt, _valueType), true, _valueToUpdate); } protected static JsonToken _initForReading(JsonParser jp) throws IOException, JsonParseException, JsonMappingException { /* First: must point to a token; if not pointing to one, advance. * This occurs before first read from JsonParser, as well as * after clearing of current token. */ JsonToken t = jp.getCurrentToken(); if (t == null) { // and then we must get something... t = jp.nextToken(); if (t == null) { /* [JACKSON-546] Throw mapping exception, since it's failure to map, * not an actual parsing problem */ throw JsonMappingException.from(jp, "No content to map due to end-of-input"); } } return t; } /** * Method called to locate deserializer for the passed root-level value. */ protected JsonDeserializer<Object> _findRootDeserializer(DeserializationContext ctxt, JavaType valueType) throws JsonMappingException { if (_rootDeserializer != null) { return _rootDeserializer; } // Sanity check: must have actual type... if (valueType == null) { throw new JsonMappingException("No value type configured for ObjectReader"); } // First: have we already seen it? JsonDeserializer<Object> deser = _rootDeserializers.get(valueType); if (deser != null) { return deser; } // Nope: need to ask provider to resolve it deser = ctxt.findRootValueDeserializer

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>(valueType); if (deser == null) { // can this happen? throw new JsonMappingException("Can not find a deserializer for type "+valueType); } _rootDeserializers.put(valueType, deser); return deser; } /** * Method called to locate deserializer ahead of time, if permitted * by configuration. Method also is NOT to throw an exception if * access fails. */ protected JsonDeserializer<Object> _prefetchRootDeserializer( DeserializationConfig config, JavaType valueType) { if (valueType == null || !_config.isEnabled(DeserializationFeature.EAGER_DESERIALIZER_FETCH)) { return null; } // already cached? JsonDeserializer<Object> deser = _rootDeserializers.get(valueType); if (deser == null) { try { // If not, need to resolve; for which we need a temporary context as well: DeserializationContext ctxt = createDeserializationContext(null, _config); deser = ctxt.findRootValueDeserializer(valueType); if (deser != null) { _rootDeserializers.put(valueType, deser); } return deser; } catch (JsonProcessingException e) { // need to swallow? } } return deser; } protected Object _unwrapAndDeserialize(JsonParser jp, DeserializationContext ctxt, JavaType rootType, JsonDeserializer<Object> deser) throws IOException, JsonParseException, JsonMappingException { String expName = _config.getRootName(); if (expName == null) { PropertyName pname = _rootNames.findRootName(rootType, _config); expName = pname.getSimpleName(); } if (jp.getCurrentToken() != JsonToken.START_OBJECT) { throw JsonMappingException.from(jp, "Current token not START_OBJECT (needed to unwrap root name '" +expName+"'), but "+jp.getCurrentToken()); } if (jp.nextToken() != JsonToken.FIELD_NAME) { throw JsonMappingException.from(jp, "Current token not FIELD_NAME (to contain expected root name '" +expName+"'), but "+jp.getCurrentToken()); } String actualName = jp.getCurrentName(); if (!expName.equals(actualName)) { throw Json

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>MappingException.from(jp, "Root name '"+actualName+"' does not match expected ('" +expName+"') for type "+rootType); } // ok, then move to value itself.... jp.nextToken(); Object result; if (_valueToUpdate == null) { result = deser.deserialize(jp, ctxt); } else { deser.deserialize(jp, ctxt, _valueToUpdate); result = _valueToUpdate; } // and last, verify that we now get matching END_OBJECT if (jp.nextToken() != JsonToken.END_OBJECT) { throw JsonMappingException.from(jp, "Current token not END_OBJECT (to match wrapper object with root name '" +expName+"'), but "+jp.getCurrentToken()); } return result; } /* /********************************************************** /* Internal methods, format auto-detection (since 2.1) /********************************************************** */ @SuppressWarnings("resource") protected Object _detectBindAndClose(byte[] src, int offset, int length) throws IOException { DataFormatReaders.Match match = _dataFormatReaders.findFormat(src, offset, length); if (!match.hasMatch()) { _reportUnkownFormat(_dataFormatReaders, match); } JsonParser jp = match.createParserWithMatch(); return match.getReader()._bindAndClose(jp, _valueToUpdate); } @SuppressWarnings("resource") protected Object _detectBindAndClose(DataFormatReaders.Match match, boolean forceClosing) throws IOException { if (!match.hasMatch()) { _reportUnkownFormat(_dataFormatReaders, match); } JsonParser p = match.createParserWithMatch(); // One more thing: we Own the input stream now; and while it's // not super clean way to do it, we must ensure closure so: if (forceClosing) { p.enable(JsonParser.Feature.AUTO_CLOSE_SOURCE); } // important: use matching ObjectReader (may not be 'this') return match.getReader()._bindAndClose(p, _valueToUpdate); } @SuppressWarnings("resource") protected <T> MappingIterator<T> _detectBindAndReadValues(DataFormatReaders.Match

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> the "value method" was annotated with * {@link com.fasterxml.jackson.databind.annotation.JsonSerialize#using}), otherwise * null */ public JsonValueSerializer(Method valueMethod, JsonSerializer<Object> ser) { super(Object.class); _accessorMethod = valueMethod; _valueSerializer = ser; _property = null; _forceTypeInformation = true; // gets reconsidered when we are contextualized } @SuppressWarnings("unchecked") public JsonValueSerializer(JsonValueSerializer src, BeanProperty property, JsonSerializer<?> ser, boolean forceTypeInfo) { super(_notNullClass(src.handledType())); _accessorMethod = src._accessorMethod; _valueSerializer = (JsonSerializer<Object>) ser; _property = property; _forceTypeInformation = forceTypeInfo; } @SuppressWarnings("unchecked") private final static Class<Object> _notNullClass(Class<?> cls) { return (cls == null) ? Object.class : (Class<Object>) cls; } public JsonValueSerializer withResolved(BeanProperty property, JsonSerializer<?> ser, boolean forceTypeInfo) { if (_property == property && _valueSerializer == ser && forceTypeInfo == _forceTypeInformation) { return this; } return new JsonValueSerializer(this, property, ser, forceTypeInfo); } /* /********************************************************** /* Post-processing /********************************************************** */ /** * We can try to find the actual serializer for value, if we can * statically figure out what the result type must be. */ @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { JsonSerializer<?> ser = _valueSerializer; if (ser == null) { /* Can only assign serializer statically if the declared type is final: * if not, we don't really know the actual type until we get the instance. */ // 10-Mar-2010, tatu: Except if static typing is to be used if (provider.isEnabled(MapperFeature.USE_STATIC_TYPING) || Modifier.isFinal(_accessorMethod.getReturnType().getModifiers())) { JavaType t = provider.constructType(_accessorMethod.getGenericReturnType()); // false -> no need

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> to cache /* 10-Mar-2010, tatu: Ideally we would actually separate out type * serializer from value serializer; but, alas, there's no access * to serializer factory at this point... */ // 05-Sep-2013, tatu: I _think_ this can be considered a primary property... ser = provider.findPrimaryPropertySerializer(t, _property); /* 09-Dec-2010, tatu: Turns out we must add special handling for * cases where "native" (aka "natural") type is being serialized, * using standard serializer */ boolean forceTypeInformation = isNaturalTypeWithStdHandling(t.getRawClass(), ser); return withResolved(property, ser, forceTypeInformation); } } else { // 05-Sep-2013, tatu: I _think_ this can be considered a primary property... ser = provider.handlePrimaryContextualization(ser, property); return withResolved(property, ser, _forceTypeInformation); } return this; } /* /********************************************************** /* Actual serialization /********************************************************** */ @Override public void serialize(Object bean, JsonGenerator jgen, SerializerProvider prov) throws IOException, JsonGenerationException { try { Object value = _accessorMethod.invoke(bean); if (value == null) { prov.defaultSerializeNull(jgen); return; } JsonSerializer<Object> ser = _valueSerializer; if (ser == null) { Class<?> c = value.getClass(); /* 10-Mar-2010, tatu: Ideally we would actually separate out type * serializer from value serializer; but, alas, there's no access * to serializer factory at this point... */ // let's cache it, may be needed soon again ser = prov.findTypedValueSerializer(c, true, _property); } ser.serialize(value, jgen, prov); } catch (IOException ioe) { throw ioe; } catch (Exception e) { Throwable t = e; // Need to unwrap this specific type, to see infinite recursion... while (t instanceof InvocationTargetException

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> && t.getCause() != null) { t = t.getCause(); } // Errors shouldn't be wrapped (and often can't, as well) if (t instanceof Error) { throw (Error) t; } // let's try to indicate the path best we can... throw JsonMappingException.wrapWithPath(t, bean, _accessorMethod.getName() + "()"); } } @Override public void serializeWithType(Object bean, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer0) throws IOException, JsonProcessingException { // Regardless of other parts, first need to find value to serialize: Object value = null; try { value = _accessorMethod.invoke(bean); // and if we got null, can also just write it directly if (value == null) { provider.defaultSerializeNull(jgen); return; } JsonSerializer<Object> ser = _valueSerializer; if (ser == null) { // already got a serializer? fabulous, that be easy... // ser = provider.findTypedValueSerializer(value.getClass(), true, _property); ser = provider.findValueSerializer(value.getClass(), _property); } else { /* 09-Dec-2010, tatu: To work around natural type's refusal to add type info, we do * this (note: type is for the wrapper type, not enclosed value!) */ if (_forceTypeInformation) { typeSer0.writeTypePrefixForScalar(bean, jgen); ser.serialize(value, jgen, provider); typeSer0.writeTypeSuffixForScalar(bean, jgen); return; } } /* 13-Feb-2013, tatu: Turns out that work-around should NOT be required * at all; it would not lead to correct behavior (as per #167). */ // and then redirect type id lookups // TypeSerializer typeSer = new TypeSerializerWrapper(typeSer0, bean); ser.serializeWithType(value, jgen, provider, typeSer0); } catch (IOException ioe) { throw ioe; } catch (Exception e) { Throwable t

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> = e; // Need to unwrap this specific type, to see infinite recursion... while (t instanceof InvocationTargetException && t.getCause() != null) { t = t.getCause(); } // Errors shouldn't be wrapped (and often can't, as well) if (t instanceof Error) { throw (Error) t; } // let's try to indicate the path best we can... throw JsonMappingException.wrapWithPath(t, bean, _accessorMethod.getName() + "()"); } } @SuppressWarnings("deprecation") @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { if (_valueSerializer instanceof SchemaAware) { return ((SchemaAware)_valueSerializer).getSchema(provider, null); } return com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode(); } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonSerializer<Object> ser = _valueSerializer; if (ser == null) { if (typeHint == null) { if (_property != null) { typeHint = _property.getType(); } if (typeHint == null) { typeHint = visitor.getProvider().constructType(_accessorMethod.getReturnType()); } } ser = visitor.getProvider().findTypedValueSerializer(typeHint, false, _property); if (ser == null) { visitor.expectAnyFormat(typeHint); return; } } ser.acceptJsonFormatVisitor(visitor, null); } protected boolean isNaturalTypeWithStdHandling(Class<?> rawType, JsonSerializer<?> ser) { // First: do we have a natural type being handled? if (rawType.isPrimitive()) { if (rawType != Integer.TYPE && rawType != Boolean.TYPE && rawType != Double.TYPE) { return false; } } else { if (rawType != String.class && rawType != Integer.class && rawType != Boolean.class && rawType != Double.class) { return false; } } return isDefaultSerializer(ser); } /* /********************************************************** /* Other methods /********************************************************** */

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.util; import com.fasterxml.jackson.databind.AnnotationIntrospector; import java.lang.reflect.Method; import java.util.*; /** * Helper class used to resolve String values (either JSON Object field * names or regular String values) into Java Enum instances. */ public class EnumResolver<T extends Enum<T>> implements java.io.Serializable { private static final long serialVersionUID = 1L; protected final Class<T> _enumClass; protected final T[] _enums; protected final HashMap<String, T> _enumsById; protected EnumResolver(Class<T> enumClass, T[] enums, HashMap<String, T> map) { _enumClass = enumClass; _enums = enums; _enumsById = map; } /** * Factory method for constructing resolver that maps from Enum.name() into * Enum value */ public static <ET extends Enum<ET>> EnumResolver<ET> constructFor(Class<ET> enumCls, AnnotationIntrospector ai) { ET[] enumValues = enumCls.getEnumConstants(); if (enumValues == null) { throw new IllegalArgumentException("No enum constants for class "+enumCls.getName()); } HashMap<String, ET> map = new HashMap<String, ET>(); for (ET e : enumValues) { map.put(ai.findEnumValue(e), e); } return new EnumResolver<ET>(enumCls, enumValues, map); } /** * Factory method for constructing resolver that maps from Enum.toString() into * Enum value */ public static <ET extends Enum<ET>> EnumResolver<ET> constructUsingToString(Class<ET> enumCls) { ET[] enumValues = enumCls.getEnumConstants(); HashMap<String, ET> map = new HashMap<String, ET>(); // from last to first, so that in case of duplicate values, first wins for (int i = enumValues.length; --i >= 0; ) { ET e = enumValues[i]; map.put(e.toString(), e); } return new EnumResolver<ET>(enumCls, enumValues, map); } public static <ET extends Enum<ET>> EnumResolver

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS><ET> constructUsingMethod(Class<ET> enumCls, Method accessor) { ET[] enumValues = enumCls.getEnumConstants(); HashMap<String, ET> map = new HashMap<String, ET>(); // from last to first, so that in case of duplicate values, first wins for (int i = enumValues.length; --i >= 0; ) { ET en = enumValues[i]; try { Object o = accessor.invoke(en); if (o != null) { map.put(o.toString(), en); } } catch (Exception e) { throw new IllegalArgumentException("Failed to access @JsonValue of Enum value "+en+": "+e.getMessage()); } } return new EnumResolver<ET>(enumCls, enumValues, map); } /** * This method is needed because of the dynamic nature of constructing Enum * resolvers. */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static EnumResolver<?> constructUnsafe(Class<?> rawEnumCls, AnnotationIntrospector ai) { /* This is oh so wrong... but at least ugliness is mostly hidden in just * this one place. */ Class<Enum> enumCls = (Class<Enum>) rawEnumCls; return constructFor(enumCls, ai); } /** * Method that needs to be used instead of {@link #constructUsingToString} * if static type of enum is not known. */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static EnumResolver<?> constructUnsafeUsingToString(Class<?> rawEnumCls) { // oh so wrong... not much that can be done tho Class<Enum> enumCls = (Class<Enum>) rawEnumCls; return constructUsingToString(enumCls); } /** * Method used when actual String serialization is indicated using @JsonValue * on a method. */ @SuppressWarnings({ "unchecked", "rawtypes" }) public static EnumResolver<?> constructUnsafeUsingMethod(Class<?> rawEnumCls, Method accessor) { // wrong as ever but: Class<Enum> enumCls = (Class<Enum>) rawEnumCls; return constructUsingMethod(enumCls, accessor); } public T findEnum(String key) { return _enums

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>ById.get(key); } public T getEnum(int index) { if (index < 0 || index >= _enums.length) { return null; } return _enums[index]; } public List<T> getEnums() { ArrayList<T> enums = new ArrayList<T>(_enums.length); for (T e : _enums) { enums.add(e); } return enums; } public Class<T> getEnumClass() { return _enumClass; } public int lastValidIndex() { return _enums.length-1; } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> boolean canCreateFromInt() { return (_fromIntCreator != null); } @Override public boolean canCreateFromLong() { return (_fromLongCreator != null); } @Override public boolean canCreateFromDouble() { return (_fromDoubleCreator != null); } @Override public boolean canCreateFromBoolean() { return (_fromBooleanCreator != null); } @Override public boolean canCreateUsingDefault() { return (_defaultCreator != null); } @Override public boolean canCreateUsingDelegate() { return _delegateType != null; } @Override public boolean canCreateFromObjectWith() { return (_withArgsCreator != null); } @Override public JavaType getDelegateType(DeserializationConfig config) { return _delegateType; } @Override public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) { return _constructorArguments; } /* /********************************************************** /* Public API implementation; instantiation from JSON Object /********************************************************** */ @Override public Object createUsingDefault(DeserializationContext ctxt) throws IOException, JsonProcessingException { if (_defaultCreator == null) { // sanity-check; caller should check throw new IllegalStateException("No default constructor for "+getValueTypeDesc()); } try { return _defaultCreator.call(); } catch (ExceptionInInitializerError e) { throw wrapException(e); } catch (Exception e) { throw wrapException(e); } } @Override public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException, JsonProcessingException { if (_withArgsCreator == null) { // sanity-check; caller should check throw new IllegalStateException("No with-args constructor for "+getValueTypeDesc()); } try { return _withArgsCreator.call(args); } catch (ExceptionInInitializerError e) { throw wrapException(e); } catch (Exception e) { throw wrapException(e); } } @Override public Object createUsingDelegate(DeserializationContext ctxt, Object delegate) throws IOException, JsonProcessingException { if (_delegateCreator == null) { // sanity-check; caller should check throw new IllegalStateException("No delegate constructor for "+getValueTypeDesc()); } try { // First simple

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> case: just delegate, no injectables if (_delegateArguments == null) { return _delegateCreator.call1(delegate); } // And then the case with at least one injectable... final int len = _delegateArguments.length; Object[] args = new Object[len]; for (int i = 0; i < len; ++i) { CreatorProperty prop = _delegateArguments[i]; if (prop == null) { // delegate args[i] = delegate; } else { // nope, injectable: args[i] = ctxt.findInjectableValue(prop.getInjectableValueId(), prop, null); } } // and then try calling with full set of arguments return _delegateCreator.call(args); } catch (ExceptionInInitializerError e) { throw wrapException(e); } catch (Exception e) { throw wrapException(e); } } /* /********************************************************** /* Public API implementation; instantiation from JSON scalars /********************************************************** */ @Override public Object createFromString(DeserializationContext ctxt, String value) throws IOException, JsonProcessingException { if (_fromStringCreator != null) { try { return _fromStringCreator.call1(value); } catch (Exception e) { throw wrapException(e); } catch (ExceptionInInitializerError e) { throw wrapException(e); } } return _createFromStringFallbacks(ctxt, value); } @Override public Object createFromInt(DeserializationContext ctxt, int value) throws IOException, JsonProcessingException { try { // First: "native" int methods work best: if (_fromIntCreator != null) { return _fromIntCreator.call1(Integer.valueOf(value)); } // but if not, can do widening conversion if (_fromLongCreator != null) { return _fromLongCreator.call1(Long.valueOf(value)); } } catch (Exception e) { throw wrapException(e); } catch (ExceptionInInitializerError e) { throw wrapException(e); } throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc() +" from Integral number ("+value+"); no single-int-arg constructor/factory

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> method"); } @Override public Object createFromLong(DeserializationContext ctxt, long value) throws IOException, JsonProcessingException { try { if (_fromLongCreator != null) { return _fromLongCreator.call1(Long.valueOf(value)); } } catch (Exception e) { throw wrapException(e); } catch (ExceptionInInitializerError e) { throw wrapException(e); } throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc() +" from Long integral number ("+value+"); no single-long-arg constructor/factory method"); } @Override public Object createFromDouble(DeserializationContext ctxt, double value) throws IOException, JsonProcessingException { try { if (_fromDoubleCreator != null) { return _fromDoubleCreator.call1(Double.valueOf(value)); } } catch (Exception e) { throw wrapException(e); } catch (ExceptionInInitializerError e) { throw wrapException(e); } throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc() +" from Floating-point number ("+value+"); no one-double/Double-arg constructor/factory method"); } @Override public Object createFromBoolean(DeserializationContext ctxt, boolean value) throws IOException, JsonProcessingException { try { if (_fromBooleanCreator != null) { return _fromBooleanCreator.call1(Boolean.valueOf(value)); } } catch (Exception e) { throw wrapException(e); } catch (ExceptionInInitializerError e) { throw wrapException(e); } throw ctxt.mappingException("Can not instantiate value of type "+getValueTypeDesc() +" from Boolean value ("+value+"); no single-boolean/Boolean-arg constructor/factory method"); } /* /********************************************************** /* Extended API: configuration mutators, accessors /********************************************************** */ @Override public AnnotatedWithParams getDelegateCreator() { return _delegateCreator; } @Override public AnnotatedWithParams getDefaultCreator() { return _defaultCreator; } @Override public AnnotatedWithParams getWithArgsCreator() { return _withArgsCreator; } @Override public AnnotatedParameter getIncomplete

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Parameter() { return _incompleteParameter; } /* /********************************************************** /* Internal methods /********************************************************** */ protected JsonMappingException wrapException(Throwable t) { while (t.getCause() != null) { t = t.getCause(); } if (t instanceof JsonMappingException) { return (JsonMappingException) t; } return new JsonMappingException("Instantiation of "+getValueTypeDesc()+" value failed: "+t.getMessage(), t); } }

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>package com.fasterxml.jackson.databind.deser.std; import java.io.IOException; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.BeanDeserializer; import com.fasterxml.jackson.databind.deser.SettableBeanProperty; import com.fasterxml.jackson.databind.util.NameTransformer; /** * Deserializer that builds on basic {@link BeanDeserializer} but * override some aspects like instance construction. */ public class ThrowableDeserializer extends BeanDeserializer { private static final long serialVersionUID = 1L; protected final static String PROP_NAME_MESSAGE = "message"; /* /************************************************************ /* Construction /************************************************************ */ public ThrowableDeserializer(BeanDeserializer baseDeserializer) { super(baseDeserializer); // need to disable this, since we do post-processing _vanillaProcessing = false; } /** * Alternative constructor used when creating "unwrapping" deserializers */ protected ThrowableDeserializer(BeanDeserializer src, NameTransformer unwrapper) { super(src, unwrapper); } @Override public JsonDeserializer<Object> unwrappingDeserializer(NameTransformer unwrapper) { if (getClass() != ThrowableDeserializer.class) { return this; } /* main thing really is to just enforce ignoring of unknown * properties; since there may be multiple unwrapped values * and properties for all may be interleaved... */ return new ThrowableDeserializer(this, unwrapper); } /* /************************************************************ /* Overridden methods /************************************************************ */ @Override public Object deserializeFromObject(JsonParser jp, DeserializationContext ctxt) throws IOException { // 30-Sep-2010, tatu: Need to allow use of @JsonCreator, so: if (_propertyBasedCreator != null) { // proper @JsonCreator return _deserializeUsingPropertyBased(jp, ctxt); } if (_delegateDeserializer != null) { return _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(jp, ctxt)); } if (_beanType.isAbstract()) { // for good measure, check this too throw JsonMappingException.from(jp, "Can not instantiate abstract type "+_bean

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Type +" (need to add/enable type information?)"); } boolean hasStringCreator = _valueInstantiator.canCreateFromString(); boolean hasDefaultCtor = _valueInstantiator.canCreateUsingDefault(); // and finally, verify we do have single-String arg constructor (if no @JsonCreator) if (!hasStringCreator && !hasDefaultCtor) { throw new JsonMappingException("Can not deserialize Throwable of type "+_beanType +" without having a default contructor, a single-String-arg constructor; or explicit @JsonCreator"); } Object throwable = null; Object[] pending = null; int pendingIx = 0; for (; jp.getCurrentToken() != JsonToken.END_OBJECT; jp.nextToken()) { String propName = jp.getCurrentName(); SettableBeanProperty prop = _beanProperties.find(propName); jp.nextToken(); // to point to field value if (prop != null) { // normal case if (throwable != null) { prop.deserializeAndSet(jp, ctxt, throwable); continue; } // nope; need to defer if (pending == null) { int len = _beanProperties.size(); pending = new Object[len + len]; } pending[pendingIx++] = prop; pending[pendingIx++] = prop.deserialize(jp, ctxt); continue; } // Maybe it's "message"? if (PROP_NAME_MESSAGE.equals(propName)) { if (hasStringCreator) { throwable = _valueInstantiator.createFromString(ctxt, jp.getText()); // any pending values? if (pending != null) { for (int i = 0, len = pendingIx; i < len; i += 2) { prop = (SettableBeanProperty)pending[i]; prop.set(throwable, pending[i+1]); } pending = null; } continue; } } /* As per [JACKSON-313], things marked as ignorable should not be * passed to any setter */ if (_ignorableProps != null && _ignorableProps.contains(propName)) { jp.skipChildren(); continue; } if (_anySetter != null) { _anySetter.deserializeAndSet(

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>, -1); } else if (_currToken == JsonToken.START_ARRAY) { _parsingContext = _parsingContext.createChildArrayContext(-1, -1); } else if (_currToken == JsonToken.END_OBJECT || _currToken == JsonToken.END_ARRAY) { // Closing JSON Object/Array? Close matching context _parsingContext = _parsingContext.getParent(); // but allow unbalanced cases too (more close markers) if (_parsingContext == null) { _parsingContext = JsonReadContext.createRootContext(null); } } return _currToken; } @Override public boolean isClosed() { return _closed; } /* /********************************************************** /* Public API, token accessors /********************************************************** */ @Override public JsonStreamContext getParsingContext() { return _parsingContext; } @Override public JsonLocation getTokenLocation() { return getCurrentLocation(); } @Override public JsonLocation getCurrentLocation() { return (_location == null) ? JsonLocation.NA : _location; } @Override public String getCurrentName() { return _parsingContext.getCurrentName(); } @Override public void overrideCurrentName(String name) { // Simple, but need to look for START_OBJECT/ARRAY's "off-by-one" thing: JsonReadContext ctxt = _parsingContext; if (_currToken == JsonToken.START_OBJECT || _currToken == JsonToken.START_ARRAY) { ctxt = ctxt.getParent(); } try { ctxt.setCurrentName(name); } catch (IOException e) { throw new RuntimeException(e); } } /* /********************************************************** /* Public API, access to token information, text /********************************************************** */ @Override public String getText() { // common cases first: if (_currToken == JsonToken.VALUE_STRING || _currToken == JsonToken.FIELD_NAME) { Object ob = _currentObject(); if (ob instanceof String) { return (String) ob; } return (ob == null) ? null : ob.toString(); } if (_currToken == null) { return null; } switch (_currToken) { case VALUE_NUMBER_INT: case VALUE_NUMBER

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS> // static if explicitly requested, or if element type is final _staticTyping = staticTyping || (et != null && et.isFinal()); _valueTypeSerializer = vts; _property = property; _elementSerializer = elementSerializer; _dynamicSerializers = PropertySerializerMap.emptyMap(); } @SuppressWarnings("unchecked") protected AsArraySerializerBase(AsArraySerializerBase<?> src, BeanProperty property, TypeSerializer vts, JsonSerializer<?> elementSerializer) { super(src); _elementType = src._elementType; _staticTyping = src._staticTyping; _valueTypeSerializer = vts; _property = property; _elementSerializer = (JsonSerializer<Object>) elementSerializer; _dynamicSerializers = src._dynamicSerializers; } public abstract AsArraySerializerBase<T> withResolved(BeanProperty property, TypeSerializer vts, JsonSerializer<?> elementSerializer); /* /********************************************************** /* Post-processing /********************************************************** */ /** * This method is needed to resolve contextual annotations like * per-property overrides, as well as do recursive call * to <code>createContextual</code> of content serializer, if * known statically. */ @Override public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException { TypeSerializer typeSer = _valueTypeSerializer; if (typeSer != null) { typeSer = typeSer.forProperty(property); } /* 29-Sep-2012, tatu: Actually, we need to do much more contextual * checking here since we finally know for sure the property, * and it may have overrides */ JsonSerializer<?> ser = null; // First: if we have a property, may have property-annotation overrides if (property != null) { AnnotatedMember m = property.getMember(); if (m != null) { Object serDef = provider.getAnnotationIntrospector().findContentSerializer(m); if (serDef != null) { ser = provider.serializerInstance(m, serDef); } } } if (ser == null) { ser = _elementSerializer; } // 18-Feb-2013, tatu: May have a

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>(value, jgen, provider); typeSer.writeTypeSuffixForArray(value, jgen); } protected abstract void serializeContents(T value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException; @SuppressWarnings("deprecation") @Override public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException { /* 15-Jan-2010, tatu: This should probably be rewritten, given that * more information about content type is actually being explicitly * passed. So there should be less need to try to re-process that * information. */ ObjectNode o = createSchemaNode("array", true); JavaType contentType = null; if (typeHint != null) { JavaType javaType = provider.constructType(typeHint); contentType = javaType.getContentType(); if (contentType == null) { // could still be parametrized (Iterators) if (typeHint instanceof ParameterizedType) { Type[] typeArgs = ((ParameterizedType) typeHint).getActualTypeArguments(); if (typeArgs.length == 1) { contentType = provider.constructType(typeArgs[0]); } } } } if (contentType == null && _elementType != null) { contentType = _elementType; } if (contentType != null) { JsonNode schemaNode = null; // 15-Oct-2010, tatu: We can't serialize plain Object.class; but what should it produce here? Untyped? if (contentType.getRawClass() != Object.class) { JsonSerializer<Object> ser = provider.findValueSerializer(contentType, _property); if (ser instanceof SchemaAware) { schemaNode = ((SchemaAware) ser).getSchema(provider, null); } } if (schemaNode == null) { schemaNode = com.fasterxml.jackson.databind.jsonschema.JsonSchema.getDefaultSchemaNode(); } o.put("items", schemaNode); } return o; } @Override public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException { JsonArrayFormatVisitor arrayVisitor = (visitor == null) ? null : visitor.expectArray

JacksonDatabind, 4

<FILEB>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<CHANGES>
try {
<CHANGEE>
<CHANGES>
} catch (Exception e) {
<CHANGEE>
<CHANGES>
throw JsonMappingException.wrapWithPath(e, String.class, ix);
}
<CHANGEE>
<FILEE>
<FILEB> protected StringArrayDeserializer(JsonDeserializer<?> deser) { super(String[].class); _elementDeserializer = (JsonDeserializer<String>) deser; } @Override public String[] deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { // Ok: must point to START_ARRAY (or equivalent) if (!jp.isExpectedStartArrayToken()) { return handleNonArray(jp, ctxt); } if (_elementDeserializer != null) { return _deserializeCustom(jp, ctxt); } final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value; if (t == JsonToken.VALUE_STRING) { value = jp.getText(); } else if (t == JsonToken.VALUE_NULL) { value = null; // since we have established that '_elementDeserializer == null' earlier } else { value = _parseString(jp, ctxt); } if (ix >= chunk.length) { chunk = buffer.appendCompletedChunk(chunk); ix = 0; } chunk[ix++] = value; } <CHANGES> <CHANGEE> // note: pass String.class, not String[].class, as we need element type for error info <CHANGES> <CHANGEE> String[] result = buffer.completeAndClearBuffer(chunk, ix, String.class); ctxt.returnObjectBuffer(buffer); return result; } /** * Offlined version used when we do not use the default deserialization method. */ protected final String[] _deserializeCustom(JsonParser jp, DeserializationContext ctxt) throws IOException { final ObjectBuffer buffer = ctxt.leaseObjectBuffer(); Object[] chunk = buffer.resetAndStart(); final JsonDeserializer<String> deser = _elementDeserializer; int ix = 0; JsonToken t; <CHANGES> <CHANGEE> while ((t = jp.nextToken()) != JsonToken.END_ARRAY) { // Ok: no need to convert Strings, but must recognize nulls String value = (t == JsonToken.VALUE_NULL) ? deser.get<SCANS>Format(typeHint); if (arrayVisitor != null) { TypeFactory tf = visitor.getProvider().getTypeFactory(); JavaType contentType = tf.moreSpecificType(_elementType, typeHint.getContentType()); if (contentType == null) { throw new JsonMappingException("Could not resolve type"); } JsonSerializer<?> valueSer = _elementSerializer; if (valueSer == null) { valueSer = visitor.getProvider().findValueSerializer(contentType, _property); } arrayVisitor.itemsFormat(valueSer, contentType); } } protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map, Class<?> type, SerializerProvider provider) throws JsonMappingException { PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property); // did we get a new map of serializers? If so, start using it if (map != result.map) { _dynamicSerializers = result.map; } return result.serializer; } protected final JsonSerializer<Object> _findAndAddDynamic(PropertySerializerMap map, JavaType type, SerializerProvider provider) throws JsonMappingException { PropertySerializerMap.SerializerAndMapResult result = map.findAndAddSecondarySerializer(type, provider, _property); if (map != result.map) { _dynamicSerializers = result.map; } return result.serializer; } }